una tuplas tupla tamaño recorrer metodos listas lista elementos convertir como arreglos acceder python tuples list-comprehension iterable-unpacking

python - tamaño - ¿Cómo convierto una tupla de tuplas a una lista unidimensional utilizando la comprensión de lista?



metodos de listas en python (7)

Estás encadenando las tuplas:

from itertools import chain print list(chain(*listOfTuples))

Debe ser bastante legible si está familiarizado con itertools , y sin la list explícita, incluso tiene su resultado en forma de generador.

Esta pregunta ya tiene una respuesta aquí:

Tengo una tupla de tuplas, por ejemplo:

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

Quiero convertir esto en una lista plana y unidimensional de todos los elementos en orden:

[1, 2, 3, 4, 5]

He estado tratando de lograr esto con la lista de comprensión. Pero parece que no puedo entenderlo. Pude lograrlo con un bucle para cada uno:

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

Pero siento que debe haber una manera de hacer esto con una lista de comprensión.

Una simple [list(tuple) for tuple in tupleOfTuples] solo le da una lista de listas, en lugar de elementos individuales. Pensé que tal vez podría basarme en esto utilizando el operador de desempaquetado para luego desempaquetar la lista, así:

[*list(tuple) for tuple in tupleOfTuples]

o

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

... pero eso no funcionó. ¿Algunas ideas? ¿O debería simplemente atenerme al bucle?


La mayoría de estas respuestas solo funcionarán para un solo nivel de aplanamiento. Para una solución más completa, intente esto (de http://rightfootin.blogspot.com/2006/09/more-on-python-flatten.html ):

def flatten(l, ltypes=(list, tuple)): ltype = type(l) l = list(l) i = 0 while i < len(l): while isinstance(l[i], ltypes): if not l[i]: l.pop(i) i -= 1 break else: l[i:i + 1] = l[i] i += 1 return ltype(l)


Me gusta usar ''reducir'' en esta situación (¡esto es para lo que se hace reducir!)

lot = ((1, 2), (3, 4), (5,)) print list(reduce(lambda t1, t2: t1 + t2, lot)) > [1,2,3,4,5]


Otra solución usando itertools.chain

>>> tupleOfTuples = ((1, 2), (3, 4), (5,)) >>> from itertools import chain >>> [x for x in chain.from_iterable(tupleOfTuples)] [1, 2, 3, 4, 5]


Para multinivel, y código legible:

def flatten(bla): output = [] for item in bla: output += flatten(item) if hasattr (item, "__iter__") or hasattr (item, "__len__") else [item] return output

No pude hacer que esto encaje en una sola línea (y puedo seguir siendo legible, incluso de lejos)


Solo usa la sum si no tienes muchas tuplas.

>>> 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]

Si tiene muchas tuplas, use la comprensión de listas o chain.from_iterable para evitar el comportamiento cuadrático de la sum .

Micro-puntos de referencia:

  • Python 2.6

    • Tupla larga de tuplas cortas

      $ 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

    • Tupla corta de tuplas largas

      $ 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

    • Tupla larga de tuplas cortas

      $ 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

    • Tupla corta de tuplas largas

      $ 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

Observación:

  • sum es más rápida si la tupla externa es corta.
  • list(chain.from_iterable(x)) es más rápido si la tupla externa es larga.

normalmente se conoce como aplanar una estructura anidada.

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

Solo para demostrar eficiencia:

>>> 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 : Por favor, no use la tuple como nombre de variable, se sombrea la función incorporada.