5

例如在这段代码中:

def product(list):
    p =1
    for i in list:
        p *= i
    return p

我找到了这段代码,但我需要能够解释它的每一部分。

4

5 回答 5

9

这是简写

p = p * i

类似于经常遇到的p += i

于 2013-10-21T11:33:40.297 回答
5

取自谷歌的第一个结果:

乘与赋值运算符,它将右操作数与左操作数相乘并将结果分配给左操作数

*=是一样的说法p = p * i

此链接包含所有运算符的列表,这些运算符的各种精彩组合。

例子

您的代码的伪代码解释如下:

assume list := {4, 6, 5, 3, 5, 1}
p := 1.

for(each number in list)
    p = the current value of p * the current number.
    // So: 1 * 4, 4 * 6, 24 * 5, 120 * 3...

return p. 
于 2013-10-21T11:34:31.027 回答
4

它与以下内容不完全相同p = p * i

>>> class A(int):
...     def __imul__(self, item):
...         print '__imul__ is running!'
...     
...     def __mul__(self, item):
...         print '__mul__ is running!'
>>> mynumber = A(10)
>>> mynumber *= 5
__imul__ is running!
>>> mynumber = A(10)
>>> mynumber * 5
__mul__ is running!

但是输出大部分是相同的,所以你应该这样对待它

于 2013-10-21T11:46:33.120 回答
4

运算符背后的想法a *= b是与 相同a = a * b。在大多数情况下(如在您的情况下)它会这样做,因此它将一个变量与一个值相乘并将结果再次存储在变量中。

使用的符号*=可能更快(取决于所涉及的类),并且无论如何它是更清晰的版本,因此应该受到青睐。它的主要优点表明变量a本身是否已经是一个复杂的表达式,例如myGiantValueField[f(42)].getValue()[3]

myGiantValueField[f(42)].getValue()[3] = myGiantValueField[f(42)].getValue()[3] * 3

当然可读性较差,并且由于代码加倍更容易修复错误

myGiantValueField[f(42)].getValue()[3] *= 3

不过,一般来说,操作符*=调用__imul__()变量的方法a并交出参数,所以它的含义与(不那么直观)b完全相同。a.__imul__(b)

a = a * b为什么和之间会有区别a *= b?三个原因同时出现在两个脑海中,但可能还有更多。

  1. 由于性能方面的原因,一个类只能实现运算*=(因此a * b虽然存在但可能是未定义的)。a *= b将一个非常大的值(例如一个巨大的矩阵)乘以一个数字有时会更好地在原地完成,以避免必须为结果分配内存(计算后可能会立即通过赋值将其复制到原始变量中)。那a = a * b是内部的东西tmp = a * ba = tmp
  2. 使用直接乘法,一个类可能会发现它的使用不直观,因此它可能会使*运算符未实现。一个示例可能是表示计算机扬声器音量的类。将音量加倍可能有意义(volumeKnob *= 2),但不建议在不使用(分配)的情况下计算它(x = volumeKnob * 2? ← 没有意义,因为它什么都不做)。
  3. 如果乘法结果的类型与 的类型不同a,我不期望或不建议实施该*=运算符,因为它会产生误导。一个例子可能是 ifabare 向量,其乘法结果将是一个矩阵(或一个数字)。这个名字__imul__已经表明它是用来迭代应用的,即不止一次。但是如果a's 的类型发生变化,这将是有问题的。
于 2013-10-21T12:32:56.293 回答
4

通常p *= i与 相同p = p * i

有时它可能会有所不同,我认为已经发布的解释还不够清楚,所以:

当 p 是可变对象时,它可能会有所不同。在这种情况下,就地*=可能会修改原始对象而不是创建新对象。比较这些中发生q的情况:

>>> p = q = [2]
>>> p *= 5
>>> p
[2, 2, 2, 2, 2]
>>> q
[2, 2, 2, 2, 2]

>>> p = q = [2]
>>> p = p * 5
>>> p
[2, 2, 2, 2, 2]
>>> q
[2]

if 也可以是不同的 whenp是一个具有副作用的复杂表达式,因为就地版本只评估子表达式一次。例如:

aList[randint(0, 5)] *= 3

不一样:

aList[randint(0, 5)] = aList[randint(0, 5)] * 3
于 2013-10-21T13:34:29.930 回答