将项添加到列表解析中的列表中

时间:2010-03-24 05:23:23

标签: python list append list-comprehension

我有一个列表,比方说a = [[1,2],[3,4],[5,6]]

我想将字符串'a'添加到列表a中的每个项目。

当我使用时:

 a = [x.append('a') for x in a] 

它返回[None,None,None]

但如果我使用:

a1 = [x.append('a') for x in a]
然后它做了一些奇怪的事情。

a,但a1不是[[1,2,'a'],[3,4,'a'],[5,6,'a']]

我不明白为什么第一个调用会返回[None, None, None],也不知道为什么第二个调用会更改a而不是a1

7 个答案:

答案 0 :(得分:28)

list.append改变列表本身并返回None。列表推导用于存储结果,如果您只想更改原始列表,则不是您想要的结果。

>>> x = [[1, 2], [3, 4], [5, 6]]
>>> for sublist in x:
...     sublist.append('a')
...
>>> x
[[1, 2, 'a'], [3, 4, 'a'], [5, 6, 'a']]

答案 1 :(得分:12)

正如其他人所说,append会改变列表本身,你不应该将它分配给变量。执行它会改变它的数据,有效地更新指向它的每个人。

但是,当我想在功能*方式中执行某些操作同时改变现有对象(而不是构造新对象,在这种情况下使用{{1})时,我会使用这个技巧},或者特别是a=[x + ['a'] for x in a])。

所以,如果你足够勇敢,你也可以这样做:

x + ['a']

这是有效的,因为>>> a=[[1,2],[3,4],[5,6]] >>> a=[x.append('a') or x for x in a] >>> a [[1, 2, 'a'], [3, 4, 'a'], [5, 6, 'a']] 会返回append,而None会继续搜索真值y值,or (它' sa x至少附加了什么)。

为什么我甚至需要这个?

假设您有一个列表,并且您希望将其中一些成员插入新列表,并相应地更新引用:

所以你有列表list

all

其中一些已插入并更新为新列表>>> all = [[], [], [], []]

x

部分>>> x = [i.append('x') or i for i in all[:2]] >>> x [['x'], ['x']] 也会插入并更新为列表all

y

>>> y = [i.append('y') or i for i in all[1:3]] 已更新:

all

>>> all [['x'], ['x', 'y'], ['y'], []] 也已更新:

x

>>> x [['x'], ['x', 'y']] 按预期生成:

y

总的来说,对于简单的任务,我建议明确使用>>> y [['x', 'y'], ['y']] 循环更新。这就是pythonic。

从技术上讲,如果您有权访问列表类,则可以将其设为函数:

for
  • functional programming基于每个语句基本上做一件事,没有副作用(因此,不变异和返回)。 def more_functional_append(self, x): self.append(x) return self 不是很有用,因为它改变了一个列表(纯函数式编程只有不可变对象),并且没有返回结果传递给其他动作(函数)。使用函数式编程概念,您可以创建无人能够读取的大型单行程序,也称为“工作安全性”#34;或者"糟糕的代码"。

答案 2 :(得分:9)

对于第一种情况,它返回[None, None, None]的原因是因为list.append函数返回None,这就是它在列表中存储的内容。

在第二种情况下,这是因为列表是可变的,每次附加值时,原始列表都会被修改。

您需要的是非就地附加运算符,例如+。即[x + ['a'] for x in a]

答案 3 :(得分:3)

(这是Mike Graham和sykora的答案的组合):

如果您只是想要就地更改值,请尝试使用常规for循环,而不是列表理解:

for sublist in a:
    sublist.append('a')

如果你想单独留下,并把结果放在a1:

a1 = [sublist + ['a'] for sublist in a]

正如他们所解释的那样,append修改了列表,但返回了None,而+只留下了列表,但返回了一个新的附加列表。

答案 4 :(得分:2)

您可以在列表推导中使用列表添加,如下所示:

  

a = [x + ['a']表示a]

中的x

这给出了期望的结果。在这种情况下,可以通过在循环之前为变量名指定['a']来提高效率,但这取决于您想要做什么。

答案 5 :(得分:0)

离开a =并在a上使用副作用:

[x.append('a') for x in a] 
print a

答案 6 :(得分:0)

在列表推导的第一个值赋值中,属性错误,'NoneType'对象没有属性'append',这有助于解释为什么你的列表a将加载None(s)。为了让我的控制台抛出错误,我使用x作为列表推导的变量,也作为迭代器。

Traceback (most recent call last):
x = [x.append('a') for x in a]
AttributeError: 'NoneType' object has no attribute 'append'

然后,我又回到了for x并且它抛出了同样的错误。

Traceback (most recent call last):
a = [x.append('a') for x in a]
AttributeError: 'NoneType' object has no attribute 'append'