【问题标题】:Asterisk symbol in PythonPython中的星号符号
【发布时间】:2014-05-27 00:12:59
【问题描述】:

我正在研究一些不同的方法来解决经典的 FizzBu​​zz 问题,并偶然发现:

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

星号是if 语句的简写吗?如果是这样,这个符号是否特定于 print

提前致谢。

【问题讨论】:

  • @alecxe: operator-overloading 不是一个不相关的标签;这在 Python 中起作用的原因正是由于运算符重载。

标签: python operators operator-overloading


【解决方案1】:

Python 中的星号实际上只是标准的乘法运算符*。它映射到它所操作的对象的__mul__ 方法,因此可以重载以具有自定义含义。这与ifprint 无关。

对于字符串(strunicode),它已被重载/覆盖以表示字符串重复,因此 "foo" * 5 的计算结果为 "foofoofoofoofoo"

>>> 'foo' * 5  # and the other way around 5 * "foo" also works
'foofoofoofoofoo'

"Fizz" * (i % 3 == 0) 只是以下的“智能”简写:

"Fizz" if i % 3 == 0 else ""

这是因为表达式 i % 3 == 0 的计算结果为布尔值,而布尔值是 Python 中整数的子类型,因此 True == 1False == 0,因此如果将字符串与布尔值“相乘”,则'要么得到相同的字符串,要么得到空字符串。

注意:我还想指出,根据我的经验/理解,Python 不鼓励这种类型的编程风格——它会降低代码的可读性(无论是新手还是老手) ) 也没有更快(事实上,可能更慢;请参阅http://pastebin.com/Q92j8qga 以获得快速基准(但有趣的是,不是在 PyPy 中:http://pastebin.com/sJtZ6uDm))。


并且* 也适用于listtuple 的实例:

>>> [1, 2, 3] * 3
[1, 2, 3, 1, 2, 3, 1, 2, 3]

>>> (1, 2, 3) * 3
(1, 2, 3, 1, 2, 3, 1, 2, 3)

您还可以为您的类型定义自己的* 运算符,使用相当于operator overloading in Python

class Foo(object):
    def __mul__(self, other):
        return "called %r with %r" % (self, other)

print Foo() * "hello"  # same as Foo().__mul__("hello")

输出:

called <__main__.Foo object at 0x10426f090> with 'hello'

* 映射到__mul__ 的情况也适用于“原始”类型,例如intfloat 等,因此3 * 4 等价于(3).__mul__(4)(其他运算符也一样) )。事实上,您甚至可以继承 int 并为 * 提供自定义行为:

class MyTrickyInt(int):
    def __mul__(self, other):
        return int.__mul__(self, other) - 1
    def __add__(self, other):
        return int.__add__(self, other) * -1

print MyTrickInt(3) * 4  # prints 11
print MyTrickyInt(3) + 2  # prints -5

...但请不要那样做 :)(事实上,完全避免子类化具体类型并没有什么坏处!)

【讨论】:

  • 可能还需要指出布尔值(TrueFalse)也是整数(分别为10)。所以"foo"*True"foo""foo"*False 是一个空字符串。
  • 当你提到这一点时,我正在添加那部分。
【解决方案2】:

asterik 用于python中的乘法。如果它适用于字符串,它会将字符串重复到指定的数字。例如,

print "test"*0
print "test"*1
print "test"*2

输出:

<blank line>
test
testtest

在你的情况下,你有or 条件,从左到右计算:

print "Fizz"*(i%3 == 0) + "Buzz"*(i%5 == 0) or i 

如果FizzBuzz 为非零/真,python 甚至不会评估i

Fizz 当 i 乘以 3 时为真(因此,对于所有可以除以 3 的 i 值,它输出 3) 同样,Buzz 对所有 5 次乘法都是正确的。 FizzBuzz 在 i 可以除以 15 时输出。 当上述两个条件都为 False 时,计算并打印 i。

【讨论】:

    猜你喜欢
    • 2011-09-25
    • 2013-08-04
    • 2011-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多