我只想了解列表理解过程中发生了什么。在列表理解中应用时,一些在“就地”列表上工作的方法似乎不起作用:
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()
没有?
答案 0 :(得分:7)
i.reverse()
将数组反转到位并且不返回任何内容,这意味着它返回None
类型。这样你就可以从列表理解中获得[None, None]
,并且同时反转先前数组的元素。
这两者不应混用,要么使用for
和x.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
。