我偶尔会使用"技巧"通过映射版本扩展列表,例如有效地计算2的幂:

from operator import mul

powers = [1]
powers += map(mul, [2] * 10, powers)

print(powers)   # prints [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]

这取决于+=会立即将map中的每个值追加到列表中,这样map就会找到它,过程就会继续.换句话说,它需要这样工作:

powers = [1]
for value in map(mul, [2] * 10, powers):
    powers.append(value)

而不是像这样首先计算并存储整个右手边,其中powers最后是[1, 2]:

powers = [1]
powers += list(map(mul, [2] * 10, powers))

是否有地方保证它能像它一样工作?我查看了Mutable Sequence Types个文档,但除了暗示s += ts.extend(t)是等价的之外,它没有说太多.它指的是MutableSequence,其source code包括:

    def extend(self, values):
        'S.extend(iterable) -- extend sequence by appending elements from the iterable'
        if values is self:
            values = list(values)
        for v in values:
            self.append(v)
    def __iadd__(self, values):
        self.extend(values)
        return self

这确实表明,它确实需要supposed个,才能像我所希望的那样工作,但是一些源代码并不像文档中的保证那样安全.

推荐答案

我没有看到任何测试或文件证明贪婪行为是有保证的;然而,我确实认为这是预期的行为,野生代码依赖于它.

FWIW,有列表的+=相当于list.extend(),所以你的"技巧"归结为:

>>> powers = [1]
>>> powers.extend(2*x for x in islice(powers, 10))
>>> powers
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]

虽然我还没有找到+=extend的保证,但我们可以保证列表迭代器在迭代时允许变异.因此,这一准则有着坚实的基础:

>>> powers = [1]
>>> for x in powers:
        if len(powers) == 10:
            break
        powers.append(2 * x)

>>> powers
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512]

1见下表第二段:

可变序列上的正向和反向迭代器访问值

Python相关问答推荐

matplotlib图中的复杂箭头形状

如何使用使用来自其他列的值的公式更新一个rabrame列?

为什么'if x is None:pass'比'x is None'单独使用更快?

什么是一种快速而优雅的方式来转换一个包含一串重复的列,而不对同一个值多次运行转换,

如何使用matplotlib查看并列直方图

比较两个有条件的数据帧并删除所有不合格的数据帧

Regex用于匹配Python中逗号分隔的AWS区域

如何关联来自两个Pandas DataFrame列的列表项?

如何在Python中画一个只能在对角线内裁剪的圆?

如何判断变量可调用函数的参数是否都属于某个子类?

在被零整除的情况下,Python不遵循IEEE-754吗?

如何在python中为列表中的每个项目分配来自另一个列表的相等数量的项目

考虑线宽的两个并排条形图

Python中字符串排列的大O表示法

用Gekko拟合两个总体的测量值

基于字典查找乘法将列添加到Pandas框架中,然后求和

我的tkinter应用程序不会改变它正在加载的文件

Python拟合线到高维点并在它们之间采样

用Arpeggio解析单行和多行注释

future 对大Pandas 群居的警告