1

我知道在 Python 列表推导中使用副作用不是一个好习惯。但我不明白为什么会发生以下情况:

In [66]: tmp = [1,2,3,4,5]; [tmp.remove(elem) for elem in tmp]
Out[66]: [None, None, None]

In [67]: tmp
Out[67]: [2, 4]

无论这是否是好的做法,列表理解的内部不应该做一些可预测的事情吗?如果以上可以预测的,有人可以解释为什么只remove发生了三个操作,为什么偶数条目是剩下的?

4

2 回答 2

6

这不是关于 listcomps,而是关于从您正在迭代的列表中删除:

>>> tmp = [1,2,3,4,5]
>>> for elem in tmp:
...     tmp.remove(elem)
... 
>>> tmp
[2, 4]

它是这样的:

>>> tmp = [1,2,3,4,5]
>>> for elem in tmp:
...     print elem, tmp
...     tmp.remove(elem)
...     print elem, tmp
... 
1 [1, 2, 3, 4, 5]
1 [2, 3, 4, 5]
3 [2, 3, 4, 5]
3 [2, 4, 5]
5 [2, 4, 5]
5 [2, 4]

首先它查看第 0 个元素,然后删除 1。所以在下一次迭代中,它想要删除第一个元素,现在是第 3 个,等等。

于 2012-10-16T23:21:02.940 回答
-1

当您直接迭代它时,从列表中删除绝不是一个好主意。编辑:哎呀,我把列表和字典混淆了。字典有一个 iteritems() 和 iterkeys() 方法,当您迭代字典并从中删除项目时,您将使用该方法。

对于列表,如果您想在列表组合中执行此操作,您可能需要复制列表。或者,交替:

[None and tmp.pop(0) for i in xrange(len(tmp))]
于 2012-10-16T23:20:41.860 回答