我瞎搞一些不同的嘶嘶声嗡嗡声脚本作为我学习Python。 我遇到了这个一个伟大的工程,但我认不出它是如何工作的。 我知道正常的嘶嘶声嗡嗡声了如何工作的循环和“如果我3%== 0和I%5 == 0”。 发生了什么我难倒的是如何“菲斯”( 不是我3%)+“ 嗡嗡 ”(我不是5%)”的作品。
x = ["Fizz"*(not i%3) + "Buzz"*(not i%5) or i for i in range(1, 100)]
我瞎搞一些不同的嘶嘶声嗡嗡声脚本作为我学习Python。 我遇到了这个一个伟大的工程,但我认不出它是如何工作的。 我知道正常的嘶嘶声嗡嗡声了如何工作的循环和“如果我3%== 0和I%5 == 0”。 发生了什么我难倒的是如何“菲斯”( 不是我3%)+“ 嗡嗡 ”(我不是5%)”的作品。
x = ["Fizz"*(not i%3) + "Buzz"*(not i%5) or i for i in range(1, 100)]
在Python中,你可以用乘法运算符复制的字符串:
print('aaa' * 3) # aaaaaaaaa
此外,布尔值隐含强制转换为上乘整数。 因此,如果你这样做
"Fizz"*(not i%3)
首先,我3%将返回取模的结果。 然后, not
运营商将其转换为任True
,如果结果为0,或False
以其他方式(通过强制它为布尔值,然后否定值)。 然后通过施加一个乘法算子, False
匝数为0,并True
匝成1。
因此,如果该号码被3整除,我们得到0取模的结果, True
在申请时not
乘时,1和字符串Fizz
复制1周时间相乘的结果。 如果不能整除,我们得到0作为操作数的乘法,有效地获取字符串Fizz
复制0次,因此一个空字符串。
这同样适用于Buzz
,并为每个结果i
的范围是两个刚刚串联。
列表理解表示为
L = [mapping-expression for element in source-list if filter-expression]
现在,将“对于在源列表元素”部分使用
for i in range(1, 100)
它迭代含整数的1至99在时刻返回一个整数的列表。
“映射表达”此处是
"Fizz"*(not i%3) + "Buzz"*(not i%5) or i
其使用i。从返回的整数“在范围为I(1,100)”
当i为被3整除或5,则i%3和I%5返回0,任何其他整数i不整除重新调谐。
(not i % 3) # return True when i is divisible by 3
(not i % 5) # returns False when i is not divisible by 5
当从返回的布尔值(未则i%3)或(未I%5)被乘以字符串“嘶嘶声”和“嗡嗡”:
"Fizz" * True # returns "Fizz"
"Buzz" * False # returns ""
然后将上面的字符串返回被级联
"Fizz" + ""
其结果是“嘶嘶声”被放置在所产生的列表和该过程的推移对于每次迭代,返回任一“嘶嘶声”或“嗡嗡”或有时倍整数i当两个字符串布尔乘法返回一个空字符串“”本身。 以来
"" + "" or i # returns i
结果列表是一样的东西[1,2, '嘶嘶声',4 '巴兹', '嘶嘶声',7,8, '嘶嘶声', '巴兹',11 '嘶嘶声',13,14, 'FizzBuzz' ......]
注意:“如果过滤器表达式”中的例子中,不使用可选的。
您可以使用:
["Fizzbuzz" if (i%3 == 0 and i %5 == 0) else "Fizz" if (i%3 == 0) else "Buzz" if (i%5 == 0) else i for i in x]
希望这将清除。
>>> 3%3
0
>>> not 3%3
True
>>>
>>> 3%2
1
>>> not 3%2
False
>>>
>>> if 0:
... print 'true'
...
>>> if 1:
... print 'true'
...
true
>>> False * 'Fizz'
''
>>> True * 'Fizz'
'Fizz'
你可以看到, 3%3
计算结果为0
和0
的值为False。 1
计算为真。
在理解,它循环为1至99每一个数字,并且如果i%3
的计算结果为True
或i=3; 3%3
i=3; 3%3
,然后"Fizz"
被打印,并且同样适用于真正的"Buzz"
如果i%5 == 0
。
如果既没有"Fizz"
也不"Buzz"
得到印刷,前部分or
这里: "Fizz"*(not i%3) + "Buzz"*(not i%5) or i
的计算结果为''+''
,以便所述or
病症的部分被打印,这仅仅是i
。
正如你可能知道, %
运算符返回给定被除数和除数的剩余部分。 此操作只返回0
时操作返回没有余数。
例如,如果i % 3 == 0
,则3
是一个因素i
。 因此i % 3 and i % 5
将只返回0
时3
或5
可以把i
。
因此not i % 3
将只返回1
,如果i
是整除3
。 所述not
声明反转输出,其中一个非零余数( true
)变为0值( false
)。 同样地,剩余零将成为值1
( true
)。
当一个像一个字符串"Fizz"
与乘以0
,它将成为空字符串。 当与乘以1
,也将保持不变。 我相信这是由于字符串的数字表示,但有人可以纠正我,如果不是这种情况。
因此, "Fizz"
和/或"Buzz"
将仅在该表达式的输出,如果存在i % 3
和/或i % 5
返回0
余数。 这意味着i
是整除3
和/或5
。
我个人最喜欢的:
#!python
from __future__ import print_function
def fizz_buzz(lower=1, upper=101):
return ["Fizz"*(x % 3 == 0) + "Buzz"*(x % 5 == 0) or str(x) \
for x in range(lower, upper)]
print('\n'.join(fizz_buzz()))
所有的动作是在列表解析表达式,大部分是在条件表达式其中或者计算为一个字符串(“嘶嘶声”,或“嗡嗡”或“嘶嘶声” +“嗡嗡”)或成整数的字符串表示为评估。
这依赖于Python的比较不寻常的(甚至可能是模糊的)*操作字符串...为“正片叠底”通过重复和串联串......还Python的关于评估语义“的道理。” (在Python空序列:字符串,列表和元组,以及其他的空箱,字典和集合和数字零值都是“假” ---用特殊无 虚假和对象一起)。
回到你的问题。 Python的对待“零字符串倍增”为空字符串。 它也把在任何算术上下文布尔对象作为1或0(如倍增)。 因此不设为i%3布尔为True如果该对象是被3整除...那是模3操作返回一个非零值。 因此,这些字符串是由一个或零(调用INT相当于(不(布尔(I%X)))...,其中X是在其他(注意一个子表达式和5 3“相乘”: 不是一元运算符,而不是一个功能,但它可以这样写一个函数调用,因为不是(x)的计算结果一样不是X ...无关括号在大多数情况下是无害的)。
我宁愿回(或收益),正是因为你可以接着使用在其他功能的表达以自然的方式结果的整数的字符串转换(例如调用字符串时,join()方法)。