Python 它为什么有效?

Python 它为什么有效?,python,string,printing,concatenation,fizzbuzz,Python,String,Printing,Concatenation,Fizzbuzz,因此,我正在学习Python,并且正在研究一系列程序思想。当然,我写了必修的汽笛,这很管用,但基本上是如果elif else Blabla的话。我在谷歌上搜索了一下,看看是否还有其他方法,找到了这条潮湿的单行线: for i in range(1,101): print("Fizz" * (i % 3 == 0) + "Buzz" * (i % 5 == 0) or i) 没有如果,没有elifs,什么都没有。我在谷歌上搜索了“字符串连接”,找到了*符号的相关信息,但不明白它在这种情

因此,我正在学习Python,并且正在研究一系列程序思想。当然,我写了必修的汽笛,这很管用,但基本上是如果elif else Blabla的话。我在谷歌上搜索了一下,看看是否还有其他方法,找到了这条潮湿的单行线:

for i in range(1,101): 
    print("Fizz" * (i % 3 == 0) + "Buzz" * (i % 5 == 0) or i)

没有如果,没有elifs,什么都没有。我在谷歌上搜索了“字符串连接”,找到了*符号的相关信息,但不明白它在这种情况下是如何工作的。有人能解释一下吗

如果(i%5==0)为真,您将打印一次字符串
“Buzz”
,或者返回
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'
[31]中的
:d=[“bar”,“foo”]
在[32]:d[32]#True中,我们得到第二个元素1
Out[33]:“foo”

把它说出来,你就会明白

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
aaaaaaa…n次…a
。如果
i%3!=0
,则
会发出嘶嘶声(i)
返回
0
<代码>“任意字符串”*0==“”。如果数字既不嘶嘶作响也不嗡嗡作响,则您将获得
打印(“”或num)
。空字符串为false,但
num
始终为True,因此它打印
num
i==3
时,
(i%3==0)
将为True

任何字符串*True都将返回该字符串。在这种情况下,将
True
视为整数
1
(因为任何乘以
1
的东西都是原来乘以的东西)

当例如
i==1
时,
(i%3==0)
将为假
(如1%3==1)

所以
string*False
==空字符串

获取上面返回的嘶嘶声和嗡嗡声字符串,并使用
+
操作符将它们连接起来


现在,在print语句中,如果连接的结果是空字符串,
运算符将使用
i
的值。

下面是正在发生的情况的细分:

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

没有如果,没有elifs,什么都没有

当然有!只是伪装而已。寻找字符串连接(即
+
)对您没有帮助,因为
*
是重复的。具体地说,string
*
n为您提供一个字符串,该字符串是一行中字符串的n个副本。此外,布尔值可以隐式转换为整数:
True
变为
1
False
变为
0
。所以

"Fizz" * (i % 3 == 0)
表示“一个
Fizz
如果
i%3==0
,如果不是,则表示无。”与
Buzz
相同

最后,结尾处的
或i
意味着如果由于两个部分都是空的而得到空字符串,则得到的是
i
实际上是指“左侧的值,除非左侧为假值,否则返回右侧的值。”

这一伎俩也在其他地方使用。Python没有直接等价于C的
?:
运算符,但由于上面提到的布尔到整数的转换,您可以使用两个元素的元组和索引操作获得接近于C的运算符。那么C的呢

a? b: c
在Python中,这意味着“
b
如果
a
为真,否则
c
”将变为:

(c, b)[a]

如果你只考虑条件:

(i % 3 == 0)
这将生成一个布尔值,说明i模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")
....

这就是“潮湿”一行的工作原理。

实际上,乘数是布尔值。@volcano,这正是我的answer@augurarm正如我在回答中所说的,它是int的一个子类。三元运算符的Python等价物是
b,如果a或者c