列表理解和到位方法

时间:2015-05-27 09:15:47

标签: python list list-comprehension

我只想了解列表理解过程中发生了什么。在列表理解中应用时,一些在“就地”列表上工作的方法似乎不起作用:

a = [[1, 2, 3], [4, 5, 6]]
i1 = id(a[0])

for i in a: i.reverse()
>>> [[3, 2, 1], [6, 5, 4]  # Works
print i1 == id(a[0])  # True, same memory address

a = [i.reverse() for i in a]
>>> [None, None]  # Doesn't work
print i1 == id(a[0])  # False, new memory address

a = [i[::-1] for i in a]
>>> [[3, 2, 1], [6, 5, 4]]  # Works!
print i1 == id(a[0])  # False

我猜这与要复制到不同内存空间的所有元素有关。为什么i[::-1]有效,而i.reverse()没有?

4 个答案:

答案 0 :(得分:7)

i.reverse()将数组反转到位并且不返回任何内容,这意味着它返回None类型。这样你就可以从列表理解中获得[None, None],并且同时反转先前数组的元素。

这两者不应混用,要么使用forx.reverse(),要么在列表理解中使用reversed(x)x[::-1]

答案 1 :(得分:3)

i.reverse()就地撤销列表并返回None

文档说的是什么:

  

list.reverse()

     

在适当的位置反转列表的元素

VS

  

reversed(seq)

     

返回反向迭代器。 seq必须是一个具有的对象   __reversed__()方法或支持序列协议   ( __len__()方法和__getitem__()方法,其整数参数从0 开始。)

<强>示例:

>>> xs = [1, 2, 3]
>>> id(xs)
140625121860208
>>> ys = xs[::-1]
>>> id(ys)
140625121924088

切片会创建一个新列表。

>>> xs.reverse()
>>> xs
[3, 2, 1]
>>> id(xs)
140625121860208

就地排序/翻转保留原始列表。

>>> zs = list(reversed(xs))
>>> zs
[1, 2, 3]
>>> id(zs)
140625121976400

reversed()返回一个迭代器;当变成列表时会创建一个新列表!如果您阅读了PEP 0322 -- Reverse Iteration,那么您会注意到reversed()不会创建新的数据结构,而只是以相反的顺序对序列进行迭代。

答案 2 :(得分:1)

这符合您的意图:

SESSION_COOKIE_DOMAIN = 'domain.com.au'

列表理解总是返回一个新列表,因此使用就地>>> a = [[1, 2, 3], [4, 5, 6]] >>> [list(reversed(i)) for i in a] [[3, 2, 1], [6, 5, 4]] 方法只返回reverse的返回值,即reverse

函数None为您提供了一个新的迭代器。将其转换为 列表与您的示例相同:

reversed()

即使它们看起来非常相似,但要区分两者, 函数>>> [i[::-1] for i in a] 和方法reversed()

答案 3 :(得分:0)

list.reverse撤消列表,然后返回None。 slice a[::-1]创建另一个列表并返回值。

列表理解将采用每个表达式的return value