Appending item to lists within a list comprehension
我有一张单子,比如说,
我想将字符串
当我使用:
1 | a = [x.append('a') for x in a] |
返回
但是如果我使用:
1 | a1 = [x.append('a') for x in a] |
然后它会做一些奇怪的事情。
我不明白为什么第一个调用返回
1 2 3 4 5 6 | >>> 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 2 3 4 | >>> 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']] |
这是因为
为什么我还要这个?
假设您有一个列表,并且希望将它的一些成员插入到新列表中,并相应地更新引用:
所以你有清单
1 | >>> all = [[], [], [], []] |
其中一些被插入并更新为新列表
1 2 3 | >>> x = [i.append('x') or i for i in all[:2]] >>> x [['x'], ['x']] |
一些
1 | >>> y = [i.append('y') or i for i in all[1:3]] |
更新
1 2 | >>> all [['x'], ['x', 'y'], ['y'], []] |
但
1 2 | >>> x [['x'], ['x', 'y']] |
预计产生
1 2 | >>> y [['x', 'y'], ['y']] |
总的来说,对于简单的任务,我建议显式地使用
从技术上讲,如果您可以访问List类,则可以将其作为一个函数:
1 2 3 | def more_functional_append(self, x): self.append(x) return self |
- 函数式编程是基于每一个基本上都在做一件事的语句,并且没有副作用(所以,不会发生变化和返回)。
append 不是很实用,因为它改变了一个列表(纯函数编程只有不变的对象),并且不返回结果传递给其他操作(函数)。使用函数式编程概念,您可以创建无人能读的大型单行程序,也称为"作业安全性"或"坏代码"。
对于第一种情况,返回
在第二种情况下,这是因为列表是可变的,每次附加值时,原始列表都会被修改。
您需要的是一个非就地附加运算符,如
(这是Mike Graham和Sykora的答案组合):
如果只想在适当的位置更改值,请尝试使用常规for循环,而不是列表理解:
1 2 | for sublist in a: sublist.append('a') |
如果您想让a单独存在,并将结果放在a1中:
1 | a1 = [sublist + ['a'] for sublist in a] |
正如他们所解释的,
您可以在列表理解中使用列表添加,例如:
a = [x + ['a'] for x in a]
这为a提供了所需的结果。在这种情况下,可以通过在循环前为变量名分配['a']来提高效率,但这取决于您想做什么。
在理解列表的第一个值分配中,属性错误"nonetype"对象没有属性"append",这有助于解释为什么列表a将加载为无。为了让我的控制台抛出错误,我使用x作为一个变量来理解列表,同时也作为迭代器。
1 2 3 | Traceback (most recent call last): x = [x.append('a') for x in a] AttributeError: 'NoneType' object has no attribute 'append' |
然后,我返回到a for x,它抛出了相同的错误。
1 2 3 | Traceback (most recent call last): a = [x.append('a') for x in a] AttributeError: 'NoneType' object has no attribute 'append' |
保留
1 2 | [x.append('a') for x in a] print a |