Python 3 调用 "list" 有奇怪的副作用
Python 3 call to "list" has odd side-effects
考虑以下两个代码片段。
片段 1:
l = range(10)
list(l)
m = reversed(l)
list(m)
l = range(-1)
list(l)
list(m)
片段 2:
l = range(10)
m = reversed(l)
l = range(-1)
list(l)
list(m)
它们之间的唯一区别是代码段 2 在其前半部分不调用 list(l)
和 list(m)
。
奇怪的是,片段 1 returns 中对 list(m)
的最终调用
[]
而片段 2 中对 list(m)
的最终调用 returns
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
这些是不同的值!
这不是我所期望的行为。据推测,代码段 1 中对 list(l)
和 list(m)
的早期调用触发了某种内存优化;请问有人能准确地向我解释发生了什么吗?
>>> l = range(10)
>>> list(l)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> m = reversed(l)
>>> list(m)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> l = range(-1)
>>> list(l)
[]
>>> list(m)
[]
>>>
>>> l = range(10)
>>> m = reversed(l)
>>> l = range(-1)
>>> list(l)
[]
>>> list(m)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
谢谢。
reversed
returns 一个一次性的迭代器:在你第一次将它提供给 list
(它从反向项目构建一个列表)后它就用完了。
在随后的运行中,它将生成空列表,因为提供的迭代器 m
已耗尽,无法生成更多值:
m = reversed(l)
print(m) # <list_reverseiterator at 0x7fd2b8518fd0>
list(m) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
list(m) # [] (exhausted)
在您的第二个片段中,您没有像在第一个片段中那样在 m
上调用 list
,因此没有耗尽它。
你只需要调用一次,最后就会得到你看到的列表。
考虑以下两个代码片段。
片段 1:
l = range(10)
list(l)
m = reversed(l)
list(m)
l = range(-1)
list(l)
list(m)
片段 2:
l = range(10)
m = reversed(l)
l = range(-1)
list(l)
list(m)
它们之间的唯一区别是代码段 2 在其前半部分不调用 list(l)
和 list(m)
。
奇怪的是,片段 1 returns 中对 list(m)
的最终调用
[]
而片段 2 中对 list(m)
的最终调用 returns
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
这些是不同的值!
这不是我所期望的行为。据推测,代码段 1 中对 list(l)
和 list(m)
的早期调用触发了某种内存优化;请问有人能准确地向我解释发生了什么吗?
>>> l = range(10)
>>> list(l)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> m = reversed(l)
>>> list(m)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> l = range(-1)
>>> list(l)
[]
>>> list(m)
[]
>>>
>>> l = range(10)
>>> m = reversed(l)
>>> l = range(-1)
>>> list(l)
[]
>>> list(m)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
谢谢。
reversed
returns 一个一次性的迭代器:在你第一次将它提供给 list
(它从反向项目构建一个列表)后它就用完了。
在随后的运行中,它将生成空列表,因为提供的迭代器 m
已耗尽,无法生成更多值:
m = reversed(l)
print(m) # <list_reverseiterator at 0x7fd2b8518fd0>
list(m) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
list(m) # [] (exhausted)
在您的第二个片段中,您没有像在第一个片段中那样在 m
上调用 list
,因此没有耗尽它。
你只需要调用一次,最后就会得到你看到的列表。