所以我正在学习Python并通过一系列程序思想。当然我写了强制性的FizzBuzz,它起作用了,但基本上就是elif else blablabla。我用谷歌搜索它是否有其他方法,并发现这个潮湿的单行:
for i in range(1,101):
print("Fizz" * (i % 3 == 0) + "Buzz" * (i % 5 == 0) or i)
没有ifs,没有elifs,没有。我用google搜索“字符串连接”并在*符号上找到了信息,但是不明白它在这种情况下是如何工作的。有人可以解释一下吗?
答案 0 :(得分:2)
在"Buzz"
为True或返回if (i % 5 == 0)
时,您将打印字符串i
:
In [5]: "foo" * 2
Out[5]: 'foofoo'
In [6]: "foo" * 3
Out[6]: 'foofoofoo'
In [7]: i = 5
In [8]: "foo" * (i % 5 == 0) or i
Out[9]: 'foo'
In [9]: "foo" * (i % 5 == 1) or i
Out[22]: 5
同样的逻辑适用于" Fizz"有时候(i % 3 == 0)
会是真的,所以我们会看到它一次,如果它是假的,我们就不会看到它。
当你在字符串上使用*
运算符时,它会重复字符串n
次,在这种情况下它最多只会一次,因为只根据布尔测试的结果打印字符串
你可以在ipython中看到True
和False
的具体信息:
In [26]: "foo" * True
Out[26]: 'foo'
In [27]: "foo" * False
Out[27]: ''
基本上True * "foo"
相当于1 * "foo"
"foo" * False
相当于0 * "foo"
Bool是int的子类,所以代码利用了这个事实,你有时看到类似的逻辑用于基于测试索引列表,尽管不推荐:
In [31]: d = ["bar","foo"]
In [32]: d[3<2] # False so we get 0 the first element
Out[32]: 'bar'
In [33]: d[3>2] # True so we get 1 the second element
Out[33]: 'foo'
答案 1 :(得分:2)
分解它,你会理解它。
def does_it_fizz(num):
return num % 3 == 0
def does_it_buzz(num):
return num % 5 == 0
for num in range(1, 101):
print("Fizz" * does_it_fizz(num) + "Buzz" * does_it_buzz(num) or num)
字符串乘法重复该字符串,因此'a' * n
为aaaaa...n times...a
。如果i % 3 != 0
,则does_it_fizz(i)
会返回0
。 "any string" * 0 == ""
。如果数字既不应该是Fizz也不应该是Buzz,那么你得print("" or num)
。空字符串为Falsey,但num
始终为Truthy,因此它会打印num
答案 2 :(得分:2)
没有ifs,没有elifs,没有。
当然有!只是伪装。寻找字符串连接(即+
)不会帮助您,因为*
是重复。具体来说,字符串*
n为您提供一个字符串,该字符串是一行中的n个字符串副本。此外,布尔值可以隐式转换为整数:True
变为1
,False
变为0
。所以
"Fizz" * (i % 3 == 0)
表示&#34;如果Fizz
,则为i % 3 == 0
,否则为无。&#34;与Buzz
相同。
最后,or i
最后意味着如果你得到空字符串,因为两个部分都是空的,那么你得到i
。 or
实际上意味着&#34;左侧的值,除非左侧是假值,在这种情况下返回右侧的值。&#34;
这个技巧也被其他地方使用了。 Python并没有直接等同于C ?:
运算符,但是由于bool-to-integer转换,你可以接近一个带有两元素元组和索引操作的运算符。上文提到的。所以C&#39>
a? b: c
如果b
为真,则表示&#34; a
,否则为c
&#34;在Python中成为这个:
(c, b)[a]
答案 3 :(得分:1)
i == 3
时,(i % 3 == 0)
将为True。
任何字符串* True都将返回字符串。在这种情况下,将True
视为整数1
会有所帮助(因为任何乘以1
的东西都是乘以的原始事物。)
例如。 i == 1
,(i % 3 == 0)
将为假(as 1 % 3 == 1)
。
所以string * False
==空字符串
获取上面返回的fizz和buzz字符串,并使用+
运算符将它们连接起来。
现在在print语句中,如果该连接的结果是空字符串,or
运算符将改为使用i
的值。
答案 4 :(得分:1)
以下是对所发生情况的细分:
for i in range(1,101):
if (i % 3 == 0):
print "Fizz"
if (i % 5 == 0):
print "Buzz"
if (i % 5 != 0 and (i % 3 != 0)):
print i
我的ide设置为Python 2.7 btw
答案 5 :(得分:1)
如果你只考虑条件:
(i % 3 == 0)
这会生成一个布尔值,表示i modulo 3的特定值是否等于0.这是3的倍数或0(0,3,6等)的情况。所以这就是你如何知道打印“Fizz”(或“Buzz”,给定其他条件)。
Python中关于字符串的一个很酷的事情是你可以有条件地打印一个字符串。例如,启动一个解释器并键入:
'foo' * True
'foo' * False
这应该导致以下输出:
'foo'
''
所以基本上,对于i的给定值,你这样做:
print("Fizz" * (0 % 3 == 0) + "Buzz" * (0 % 5 == 0) or i) -> print("Fizz" * True + "Buzz" * True or i) -> printf('Fizz'+'Buzz')
print("Fizz" * (1 % 3 == 0) + "Buzz" * (1 % 5 == 0) or i) -> print("Fizz" * False + "Buzz" * False or i) -> printf(1)
print("Fizz" * (2 % 3 == 0) + "Buzz" * (2 % 5 == 0) or i) -> print("Fizz" * False + "Buzz" * False or i) -> printf(2)
print("Fizz" * (3 % 3 == 0) + "Buzz" * (3 % 5 == 0) or i) -> print("Fizz" * True + "Buzz" * False or i) -> printf("Fizz")
....
这就是“潮湿”的一条班轮的运作方式。