Python列表推导式与for循环行为的比较

5

编辑:我的逻辑有些笨拙,none只是推导调用的返回值。 好的,我正在用Python运行一些测试,并遇到执行顺序上的一点差异,这让我理解了它的实现方式,但我想向你们这些优秀的人员请教一下,看看我是否正确,或者还有什么需要注意的地方。考虑以下代码:

>>> a = ["a","b","c","d","e"]
>>> def test(self,arg):
...     print "testing %s" %(arg)
...     a.pop()
... 
>>>[test(elem) for elem in a]
testing a
testing b
testing c
[None, None, None]
>>> a
['a', 'b']
#now we try another syntax
>>> a = ["a","b","c","d","e"]
>>> for elem in a:
...     print "elem is %s"%(elem)
...     test(elem)
... 
elem is a
testing a
elem is b
testing b
elem is c
testing c
>>> a
['a', 'b']
>>> 

现在,这告诉我for elem in a:获取下一个可迭代元素,然后应用主体,而推导式在实际执行函数中的每个元素之前调用函数,因此从函数(pop)修改列表导致] none,none,none]

这样对吗?这里发生了什么?
谢谢

2
test() 不返回任何内容,因此它返回 None。(另外,你应该删除 self 参数。) - Sven Marnach
是的,我只是在玩,我想看看它们是否真的等效... 但这里有执行顺序的问题。 - cromestant
6
在遍历集合时改变其大小(添加或删除项)是不被允许的行为。 - user395760
当然可以,我并不怀疑这一点。 - cromestant
for循环和列表推导在这种情况下有相同的效果吗?它们都会打印出“testing a, testing b, testing c”,然后a==['a','b']。它们之间有什么区别??? - Ishtar
3个回答

4

您的test函数没有return语句,因此在列表推导中使用它会导致得到一个由None组成的列表。交互式Python提示符会打印出最后一个语句返回的内容。

示例:

>>> def noop(x): pass
... 
>>> [noop(i) for i in range(5)]
[None, None, None, None, None]

实际上,在您提出的问题中,列表推导式和 for 循环的工作方式没有任何区别。


1
>>> a = ["a","b","c","d","e"]
>>> i = iter(a)
>>> next(i)
'a'
>>> a.pop()
'e'
>>> next(i)
'b'
>>> a.pop()
'd'
>>> next(i)
'c'
>>> a.pop()
'c'
>>> next(i)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>>

0

它已经到达了"c",然后在列表中没有元素了。由于test没有返回任何内容,因此您会得到[None, None, None]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接