0
a=[['1','3','2'],['11','22','33']]
k = [(float(a[i][j]) for j in range(0,3)) for i in range(0,2)]
>>> print k
[<generator object <genexpr> at 0x7f1a9d568f50>, <generator object <genexpr> at 0x7f1a9d568fa0>]

but I want to get [(1,3,2),(11,22,33)] why does list comprehension produce a generator?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
lily
  • 515
  • 7
  • 20

2 Answers2

9

You have a generator expression ((x for x in ...)) inside a list comprehension ([x for x in ...]). This will return a list of generator objects. Change the code like so

a = [['1','3','2'],['11','22','33']]
k = [[float(a[i][j]) for j in range(0,3)] for i in range(0,2)]

print(k)
# [[1.0, 3.0, 2.0], [11.0, 22.0, 33.0]]
Ffisegydd
  • 51,807
  • 15
  • 147
  • 125
  • is it possible to get [(1,3,2),(11,22,33)]? – lily Jan 15 '15 at 16:42
  • 1
    Yes. You can wrap the list comprehension in a tuple call so `[tuple([...]) for ...]`. However, I'd suggest you look up Martijn Pieter's answer as he explains how you can get what you want in a much neater fashion :) – Ffisegydd Jan 15 '15 at 16:43
6

You are using a generator expression in your list comprehension expression:

(float(a[i][j]) for j in range(0,3))

If you wanted that to execute like a list comprehension, make that a list comprehension too:

[[float(a[i][j]) for j in range(3)] for i in range(2)]

If you need those to be tuples, then you'll have to explicitly call tuple():

[tuple(float(a[i][j]) for j in range(3)) for i in range(2)]

The tuple() callable will drive the generator expression to produce a tuple of those values. There is no such thing as a tuple comprehension, otherwise.

Rather than use ranges, you can loop over a and the nested lists directly:

[tuple(float(v) for v in nested) for nested in a]

Demo:

>>> a=[['1','3','2'],['11','22','33']]
>>> [tuple(float(v) for v in nested) for nested in a]
[(1.0, 3.0, 2.0), (11.0, 22.0, 33.0)]
Community
  • 1
  • 1
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343