列表理解和就地方法
List comprehension and in place methods
我只是想了解在列表理解过程中发生了什么。某些适用于列表 'in-place' 的方法在应用于列表理解时似乎不起作用:
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
我猜这与所有元素都被复制到不同的内存有关space。为什么 i[::-1]
有效而 i.reverse()
无效?
i.reverse()
就地反转数组并且不 return 任何东西,这意味着它是 returns None
类型。这样你就可以从列表理解中获得 [None, None]
并且先前数组的元素同时被反转。
这两个不应该混用,要么使用 for
和 x.reverse()
,要么在列表理解中使用 reversed(x)
或 x[::-1]
。
i.reverse()
就地反转列表并且 returns None
.
文档怎么说:
list.reverse()
Reverse the elements of the list, in place
对比
reversed(seq)
Return a reverse iterator. seq must be an object which has a
__reversed__()
method or supports the sequence protocol
(the __len__()
method and the __getitem__()
method with integer arguments starting at 0
).
示例:
>>> xs = [1, 2, 3]
>>> id(xs)
140625121860208
>>> ys = xs[::-1]
>>> id(ys)
140625121924088
切片创建一个新列表。
>>> xs.reverse()
>>> xs
[3, 2, 1]
>>> id(xs)
140625121860208
就地 sorting/reversing 保留原始列表。
>>> zs = list(reversed(xs))
>>> zs
[1, 2, 3]
>>> id(zs)
140625121976400
reversed()
returns 一个迭代器;当变成一个列表时,它会创建一个新列表!如果您读过 PEP 0322 -- Reverse Iteration,您会注意到 reversed()
不会创建新的数据结构,而只是以相反的顺序迭代序列。
这就是你想要的:
>>> a = [[1, 2, 3], [4, 5, 6]]
>>> [list(reversed(i)) for i in a]
[[3, 2, 1], [6, 5, 4]]
列表理解总是 return 一个新列表,所以使用就地 reverse
方法只是 returns reverse
的 return 值,即 None
.
函数reversed()
为您提供了一个新的迭代器。将其转换为
对于您的示例,列表与以下内容相同:
>>> [i[::-1] for i in a]
尽管它们看起来非常相似,但区分两者很重要,
函数 reversed()
和方法 obj.reverse()
list.reverse
原地反转列表,return None
。
而 slice a[::-1]
创建另一个列表并 return 作为值。
列表理解将采用每个表达式的 return value
。
我只是想了解在列表理解过程中发生了什么。某些适用于列表 'in-place' 的方法在应用于列表理解时似乎不起作用:
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
我猜这与所有元素都被复制到不同的内存有关space。为什么 i[::-1]
有效而 i.reverse()
无效?
i.reverse()
就地反转数组并且不 return 任何东西,这意味着它是 returns None
类型。这样你就可以从列表理解中获得 [None, None]
并且先前数组的元素同时被反转。
这两个不应该混用,要么使用 for
和 x.reverse()
,要么在列表理解中使用 reversed(x)
或 x[::-1]
。
i.reverse()
就地反转列表并且 returns None
.
文档怎么说:
list.reverse()
Reverse the elements of the list, in place
对比
reversed(seq)
Return a reverse iterator. seq must be an object which has a
__reversed__()
method or supports the sequence protocol (the__len__()
method and the__getitem__()
method with integer arguments starting at0
).
示例:
>>> xs = [1, 2, 3]
>>> id(xs)
140625121860208
>>> ys = xs[::-1]
>>> id(ys)
140625121924088
切片创建一个新列表。
>>> xs.reverse()
>>> xs
[3, 2, 1]
>>> id(xs)
140625121860208
就地 sorting/reversing 保留原始列表。
>>> zs = list(reversed(xs))
>>> zs
[1, 2, 3]
>>> id(zs)
140625121976400
reversed()
returns 一个迭代器;当变成一个列表时,它会创建一个新列表!如果您读过 PEP 0322 -- Reverse Iteration,您会注意到 reversed()
不会创建新的数据结构,而只是以相反的顺序迭代序列。
这就是你想要的:
>>> a = [[1, 2, 3], [4, 5, 6]]
>>> [list(reversed(i)) for i in a]
[[3, 2, 1], [6, 5, 4]]
列表理解总是 return 一个新列表,所以使用就地 reverse
方法只是 returns reverse
的 return 值,即 None
.
函数reversed()
为您提供了一个新的迭代器。将其转换为
对于您的示例,列表与以下内容相同:
>>> [i[::-1] for i in a]
尽管它们看起来非常相似,但区分两者很重要,
函数 reversed()
和方法 obj.reverse()
list.reverse
原地反转列表,return None
。
而 slice a[::-1]
创建另一个列表并 return 作为值。
列表理解将采用每个表达式的 return value
。