我有以下代码:
l = [(i for j in xrange(2)) for i in xrange(3)]
print list(l[0])
for i in l:
print list(i)
以下输出:
[2, 2]
[]
[<generator object <genexpr> at 0x022B97B0>, <generator object <genexpr> at 0x022B97B0>]
[<generator object <genexpr> at 0x022B9D00>, <generator object <genexpr> at 0x022B9D00>]
前两行是预期的结果,但最后两个结果看起来适合我。 我想索引l [0]访问之间没有区别,或者通过迭代器访问循环中list的每个元素。你能帮我吗?
答案 0 :(得分:1)
此问题是由变量名称冲突引起的。 list comprehension使用的变量共享全局命名空间,而不是在python 2.x中使用孤立的命名空间。因此,将变量名称从i
更改为不同的名称会为您提供正确的结果。
l = [(i for j in xrange(2)) for i in xrange(3)]
print list(l[0])
# Change variable name to `value`
for value in l:
print list(value)
这将打印:
[2, 2]
[]
[2, 2]
[2, 2]
为了进一步证明这一点,你可以这样做:
l = [(i for j in xrange(2)) for i in xrange(3)]
print list(l[0])
i = 'another value'
for value in l:
print list(value)
这会给你:
[2, 2]
[]
['another value', 'another value']
['another value', 'another value']
答案 1 :(得分:0)
问题是你在列表理解中使用了变量i
,i
会与你期望的完全不同。
print i
>> 2
因此,将其更改为item
将产生正确的结果。
for item in enumerate(l):
list(item)
>> [2, 2]
>> [2, 2]
>> [2, 2]
答案 2 :(得分:0)
列表i
中的变量l
不是列表列表,而是对生成器对象的引用(每次迭代不同)。
>>> l = [(i for j in xrange(2)) for i in xrange(3)]
>>> for i in l:
... print i
...
<generator object <genexpr> at 0xb71ed194>
<generator object <genexpr> at 0xb71ed1bc>
<generator object <genexpr> at 0xb71ed1e4>
PEP 0289定义了Generator expressions
。它似乎与list comprehension非常相似。直接从PEP 0289引用:
“列表推导的经验表明它们在整个Python中具有广泛的实用性。但是,许多用例不需要在内存中创建完整的列表。相反,它们只需要迭代一个元素。时间“。
另见this。在您的情况下,请尝试以下操作:
l = [(i for j in xrange(2)) for i in xrange(3)]
k = [[i for j in xrange(2)] for i in xrange(3)]
print list(l[0])
for i in l:
print list(i)
for i in k:
print list(i)
在上面的代码中,l
是生成器对象列表,而k
是列表列表。
现在,逐一考虑它们。首先检查列表l
:
>>> l = [(i for j in xrange(2)) for i in xrange(3)]
>>> for i in l:
... print list(i)
...
[<generator object <genexpr> at 0xb71c70cc>, <generator object <genexpr> at 0xb71c70cc>]
[<generator object <genexpr> at 0xb71c70a4>, <generator object <genexpr> at 0xb71c70a4>]
[<generator object <genexpr> at 0xb71c71bc>, <generator object <genexpr> at 0xb71c71bc>]
>>> for i in l:
... print list(i)
...
[]
[]
[]
您只能迭代生成器对象一次。但是,在其他情况下,我们可以根据需要使用多次。
>>> k = [[i for j in xrange(2)] for i in xrange(3)]
>>> for i in k:
... print list(i)
...
[0, 0]
[1, 1]
[2, 2]
>>> for i in k:
... print list(i)
...
[0, 0]
[1, 1]
[2, 2]
但是,如果您需要一个元组列表,那么您可以使用它:
>>> l = [tuple(i for j in xrange(2)) for i in xrange(3)]
>>> l
[(0, 0), (1, 1), (2, 2)]
>>> for i in l:
... print i
...
(0, 0)
(1, 1)
(2, 2)
>>> for i in l:
... print i
...
(0, 0)
(1, 1)
(2, 2)