Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I convert a tuple of tuples to a one-dimensional list using list comprehension? [duplicate]

I have a tuple of tuples - for example:

tupleOfTuples = ((1, 2), (3, 4), (5,)) 

I want to convert this into a flat, one-dimensional list of all the elements in order:

[1, 2, 3, 4, 5] 

I've been trying to accomplish this with list comprehension. But I can't seem to figure it out. I was able to accomplish it with a for-each loop:

myList = [] for tuple in tupleOfTuples:    myList = myList + list(tuple) 

But I feel like there must be a way to do this with a list comprehension.

A simple [list(tuple) for tuple in tupleOfTuples] just gives you a list of lists, instead of individual elements. I thought I could perhaps build on this by using the unpacking operator to then unpack the list, like so:

[*list(tuple) for tuple in tupleOfTuples] 

or

[*(list(tuple)) for tuple in tupleOfTuples] 

... but that didn't work. Any ideas? Or should I just stick to the loop?

like image 962
froadie Avatar asked Jul 08 '10 13:07

froadie


People also ask

How do you convert a tuple to a list?

To convert a tuple into list in Python, call list() builtin function and pass the tuple as argument to the function. list() returns a new list generated from the items of the given tuple.

How do you convert a tuple to a list of tuples in Python?

To convert a tuple to list in Python, use the list() method. The list() is a built-in Python method that takes a tuple as an argument and returns the list. The list() takes sequence types and converts them to lists.

Can we convert list to tuple and tuple to list in Python?

tuple () function can take any iterable as an argument and convert it into a tuple object. As you wish to convert a python list to a tuple, you can pass the entire list as a parameter within the tuple() function, and it will return the tuple data type as an output.

How do you map a tuple to a list in Python?

Use the map() Function to Convert a Tuple to a List in Python. The map() function can apply a function to each item in an iterable. We can use it with the list() function to convert tuple containing tuples to a nested list.


2 Answers

it's typically referred to as flattening a nested structure.

>>> tupleOfTuples = ((1, 2), (3, 4), (5,)) >>> [element for tupl in tupleOfTuples for element in tupl] [1, 2, 3, 4, 5] 

Just to demonstrate efficiency:

>>> import timeit >>> it = lambda: list(chain(*tupleOfTuples)) >>> timeit.timeit(it) 2.1475738355700913 >>> lc = lambda: [element for tupl in tupleOfTuples for element in tupl] >>> timeit.timeit(lc) 1.5745135182887857 

ETA: Please don't use tuple as a variable name, it shadows built-in.

like image 95
SilentGhost Avatar answered Sep 18 '22 22:09

SilentGhost


Just use sum if you don't have a lot of tuples.

>>> tupleOfTuples = ((1, 2), (3, 4), (5,)) >>> sum(tupleOfTuples, ()) (1, 2, 3, 4, 5) >>> list(sum(tupleOfTuples, ())) # if you really need a list [1, 2, 3, 4, 5] 

If you do have a lot of tuples, use list comprehension or chain.from_iterable to prevent the quadratic behavior of sum.


Micro-benchmarks:

  • Python 2.6

    • Long tuple of short tuples

      $ python2.6 -m timeit -s 'tot = ((1, 2), )*500' '[element for tupl in tot for element in tupl]' 10000 loops, best of 3: 134 usec per loop $ python2.6 -m timeit -s 'tot = ((1, 2), )*500' 'list(sum(tot, ()))' 1000 loops, best of 3: 1.1 msec per loop $ python2.6 -m timeit -s 'tot = ((1, 2), )*500; from itertools import chain; ci = chain.from_iterable' 'list(ci(tot))' 10000 loops, best of 3: 60.1 usec per loop $ python2.6 -m timeit -s 'tot = ((1, 2), )*500; from itertools import chain' 'list(chain(*tot))' 10000 loops, best of 3: 64.8 usec per loop 
    • Short tuple of long tuples

      $ python2.6 -m timeit -s 'tot = ((1, )*500, (2, )*500)' '[element for tupl in tot for element in tupl]' 10000 loops, best of 3: 65.6 usec per loop $ python2.6 -m timeit -s 'tot = ((1, )*500, (2, )*500)' 'list(sum(tot, ()))' 100000 loops, best of 3: 16.9 usec per loop $ python2.6 -m timeit -s 'tot = ((1, )*500, (2, )*500); from itertools import chain; ci = chain.from_iterable' 'list(ci(tot))' 10000 loops, best of 3: 25.8 usec per loop $ python2.6 -m timeit -s 'tot = ((1, )*500, (2, )*500); from itertools import chain' 'list(chain(*tot))' 10000 loops, best of 3: 26.5 usec per loop 
  • Python 3.1

    • Long tuple of short tuples

      $ python3.1 -m timeit -s 'tot = ((1, 2), )*500' '[element for tupl in tot for element in tupl]' 10000 loops, best of 3: 121 usec per loop $ python3.1 -m timeit -s 'tot = ((1, 2), )*500' 'list(sum(tot, ()))' 1000 loops, best of 3: 1.09 msec per loop $ python3.1 -m timeit -s 'tot = ((1, 2), )*500; from itertools import chain; ci = chain.from_iterable' 'list(ci(tot))' 10000 loops, best of 3: 59.5 usec per loop $ python3.1 -m timeit -s 'tot = ((1, 2), )*500; from itertools import chain' 'list(chain(*tot))' 10000 loops, best of 3: 63.2 usec per loop 
    • Short tuple of long tuples

      $ python3.1 -m timeit -s 'tot = ((1, )*500, (2, )*500)' '[element for tupl in tot for element in tupl]' 10000 loops, best of 3: 66.1 usec per loop $ python3.1 -m timeit -s 'tot = ((1, )*500, (2, )*500)' 'list(sum(tot, ()))' 100000 loops, best of 3: 16.3 usec per loop $ python3.1 -m timeit -s 'tot = ((1, )*500, (2, )*500); from itertools import chain; ci = chain.from_iterable' 'list(ci(tot))' 10000 loops, best of 3: 25.4 usec per loop $ python3.1 -m timeit -s 'tot = ((1, )*500, (2, )*500); from itertools import chain' 'list(chain(*tot))' 10000 loops, best of 3: 25.6 usec per loop 

Observation:

  • sum is faster if the outer tuple is short.
  • list(chain.from_iterable(x)) is faster if the outer tuple is long.
like image 31
kennytm Avatar answered Sep 19 '22 22:09

kennytm