Use list comprehension to build a tuple

Question:

How can I use list comprehension to build a tuple of 2-tuple from a list. It would be equivalent to

tup = ()
for element in alist:
    tup = tup + ((element.foo, element.bar),)
Asked By: Lim H.

||

Answers:

tup = tuple((element.foo, element.bar) for element in alist)

Technically, it’s a generator expression. It’s like a list comprehension, but it’s evaluated lazily and won’t need to allocate memory for an intermediate list.

For completeness, the list comprehension would look like this:

tup = tuple([(element.foo, element.bar) for element in alist])

 

PS: attrgetter is not faster (alist has a million items here):

In [37]: %timeit tuple([(element.foo, element.bar) for element in alist])
1 loops, best of 3: 165 ms per loop

In [38]: %timeit tuple((element.foo, element.bar) for element in alist)
10 loops, best of 3: 155 ms per loop

In [39]: %timeit tuple(map(operator.attrgetter('foo','bar'), alist))
1 loops, best of 3: 283 ms per loop

In [40]: getter = operator.attrgetter('foo','bar')

In [41]: %timeit tuple(map(getter, alist))
1 loops, best of 3: 284 ms per loop

In [46]: %timeit tuple(imap(getter, alist))
1 loops, best of 3: 264 ms per loop
Answered By: Pavel Anossov

You may use the following expression

tup = *[(element.foo, element.bar) for element in alist]

This will first of all generate a list of tuples and then it will convert that list of tuples into a tuple of tuples.

Answered By: manav014

Despite the already working answer:

tup = tuple((element.foo, element.bar) for element in alist)

The shortest way is (comma at end is mandatory!):

tup = *((elements.foo, elements.bar) for elements in alist),

It’ s arguable which solution is the more readable or more pythonic.

Explanation of: *(...),

Answered By: tturbo
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.