迭代时编辑列表(pythonic方式!)

时间:2016-04-06 13:49:24

标签: python list

所以,我知道如何做到这一点,但对我来说它似乎并不是pythonic。有没有更简洁的方法呢?

arr = list(range(10))
print(arr)
for n in range(len(arr)):
    # Perform som operation on the element that changes the value "in place"
    arr[n] += 1
print(arr)

输出(这就是我想要的):

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

3 个答案:

答案 0 :(得分:5)

您可以使用list comprehension

arr = [i + 1 for i in arr]

这会生成 new 列表;在上面的例子中,我将结果反弹为同名。

如果您对列表有多个引用并且需要就地更改它(以便其他引用看到更改),请分配给标识片([:])以更新列表的所有索引而不是重新命名:

arr[:] = [i + 1 for i in arr]

这首先创建一个新的列表对象,然后Python足够聪明,可以看到两个列表的大小相同,并且在重新释放第二个列表之前只复制元素。

在这种情况下,您甚至可以使用生成器表达式来避免创建额外的列表:

arr[:] = (i + 1 for i in arr)

这会将原始元素移到一边为新元素腾出空间,但是没有为此创建新的Python列表对象。这应该是更高的内存效率。

答案 1 :(得分:3)

使用列表理解:

arr = [x + 1 for x in arr]

答案 2 :(得分:3)

他们说了什么。但是如果你想在创建列表的同时进行操作,你可以这样做:

arr = [u + 1 for u in range(10)]

我认为您正在使用Python 3.如果您正在使用Python 2,那么将range更改为xrange(除非列表大小非常小),因为Python 2 range函数返回实际的list,但xrange返回一个迭代器; Python 3 range函数返回一个与旧xrange类似的迭代器(但有一些改进)。

如果arr是您要修改的现有list而未使用新的list对象替换当前list对象,则可以执行

arr[:] = [u + 1 for u in arr]

以下是一些代码,用于说明在作业左侧使用arrarr[:]之间的区别。

arr = list(range(10))
b = arr
print(id(arr), id(b))
arr = [u + 1 for u in arr]
print(id(arr), id(b))
print(arr, b)

c = arr
print(id(arr), id(c))
arr[:] = [u + 1 for u in arr]
print(id(arr), id(c))
print(arr, c)

<强>输出

3073636268 3073636268
3073629964 3073636268
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
3073629964 3073629964
3073629964 3073629964
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11] [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

因此arr = [u + 1 for u in arr]将名称arr绑定到新的列表对象,但arr[:] = [u + 1 for u in arr]有效地改变了现有的列表对象。 &#34;引擎盖下&#34;它创建一个新的临时列表对象,然后将其内容复制到旧的列表对象。