Python列表推导和extend()函数

5

学习Python(2.7.1),但是花了几个小时都无法理解以下内容:

>>> a = [1, 2]
>>> b = [3, 4]
>>> 
>>> a.extend([b[0]])
>>> a
[1, 2, 3]
>>> 
>>> a.extend([b[1]])
>>> a
[1, 2, 3, 4]
>>> 
>>> m = [a.extend([b[i]]) for i in range(len(b))] # list of lists
>>> m
[None, None]

第一和第二个扩展正常工作,但是当在列表推导式中压缩相同内容时会失败。我做错了什么?

1
预期的正确输出是什么? - User
预期输出,你是对的,我应该提到的。 - user3012707
哎呀,按了回车键,是我的错误。预期输出是[[1, 2, 3], [1, 2, 3, 4]],即一个列表的列表。 - user3012707
6个回答

7

extend在原地修改列表。

>>> [a + b[0:i] for i in range(len(b)+1)]
[[1, 2], [1, 2, 3], [1, 2, 3, 4]]

谢谢,这正是我想要的。这个理解可以分配给一个变量m,就像你说的那样。 - user3012707

4

list.extend()方法直接扩展了列表,是一种原地修改的方式。在Python标准库中,那些对对象进行原地修改的方法总是返回None(默认值);你的列表解析式执行了两次a.extend(),因此结果列表由两个None返回值组成。

否则,你的a.extend()调用完全正常;如果打印a,它会显示:

[1, 2, 3, 4, 3, 4]

在Python解释器中,您看不到None返回值,因为解释器从不回显None结果。您可以明确测试该值:

>>> a = []
>>> a.extend(['foo', 'bar']) is None
True
>>> a
['foo', 'bar']

2

extend函数会在原列表中添加你提供的值,并返回None。这就是为什么你的列表中有两个None值的原因。我建议你重写你的推导式,像这样:

a = [1, 2]
b = [3, 4]
m = [a + [v] for v in b] # m is [[1,2,3],[1,2,4]]

感谢您的回答:列表中包含列表几乎正确。然而,我需要的结果是一个不断增长的列表:[[1, 2, 3],[1, 2, 3, 4]]。 - user3012707

2
对于python列表,改变列表的方法是原地进行的,并且返回None。这适用于extend以及appendremoveinsert等方法。

针对一个较早的问题,我草拟了一个list子类,它将按照你预期的方式运行。

为什么[].append()在Python中不起作用?

这是用于教育目的。关于正反面的讨论,请参考我的回答中的评论。

我喜欢这种方法可以链接多个方法并以流畅的方式工作,例如:

li = FluentList()
li.extend([1,4,6]).remove(4).append(7).insert(1,10).reverse().sort(key=lambda x:x%2)

可以实现。

2
extend 的返回值为 None

谢谢。这解释了其中的一部分。 - user3012707

0

a.extend() 返回 None

你可能想要其中之一:

>>> m = a + b
>>> m
[1, 2, 3, 4]
>>> a.extend(b)
>>> a
[1, 2, 3, 4]

除此之外,如果你想迭代一个列表中的所有元素,你可以这样做:

m = [somefunction(element) for element in somelist]

或者

for element in somelist:
    do_some_thing(element)

在大多数情况下,不需要遍历索引。
如果您想向列表中添加一个元素,应该使用 somelist.append(element) 而不是 `somelist.extend([element])`。

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