Your variable i
in the list l
is not a list of lists but instead it is a reference to a generator object (different in each iteration).
>>> 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 defines about the Generator expressions
. It seems quite similar to list comprehension. Quoting directly from PEP 0289:
"Experience with list comprehensions has shown their wide-spread utility throughout Python. However, many of the use cases do not need to have a full list created in memory. Instead, they only need to iterate over the elements one at a time."
Also see this. In your case, try this for instance:
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)
In the above code, l
is a list of generator objects while k
is a list of lists.
Now, consider them one by one. First check for the list 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)
...
[]
[]
[]
You can iterate over a generator object only once. But, in other case, we can use as many times as we want.
>>> 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]
But, if you needed a list of tuples then you can use this:
>>> 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)