Как преобразовать кортеж кортежей в одномерный список, используя понимание списка?

У меня есть кортеж кортежей – например:

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

Я хочу преобразовать это в плоский, одномерный список всех элементов в порядке:

 [1, 2, 3, 4, 5] 

Я пытался это сделать с пониманием списка. Но я не могу понять это. Я смог выполнить его с помощью цикла for:

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

Но я чувствую, что должен быть способ сделать это с пониманием списка.

Простой [list(tuple) for tuple in tupleOfTuples] просто дает вам список списков вместо отдельных элементов. Я думал, что, возможно, я опишу это, используя оператор распаковки, чтобы распаковать список, например:

 [*list(tuple) for tuple in tupleOfTuples] 

или

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

… но это не сработало. Есть идеи? Или я должен просто придерживаться петли?

7 Solutions collect form web for “Как преобразовать кортеж кортежей в одномерный список, используя понимание списка?”

его обычно называют уплощением вложенной структуры.

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

Просто чтобы продемонстрировать эффективность:

 >>> 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 : Пожалуйста, не используйте tuple в качестве имени переменной, он теней встроен.

Просто используйте sum если у вас нет большого количества кортежей.

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

Если у вас много кортежей, используйте понимание списка или chain.from_iterable чтобы предотвратить квадратичное поведение sum .


Микро-тесты:

  • Python 2.6

    • Длинные кортежи коротких кортежей

       $ 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 
    • Короткий кортеж длинных кортежей

       $ 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

    • Длинные кортежи коротких кортежей

       $ 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 
    • Короткий кортеж длинных кортежей

       $ 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 

Наблюдение:

  • sum быстрее, если внешний кортеж короток.
  • list(chain.from_iterable(x)) быстрее, если внешний кортеж длинный.

Вы цепляете кортежи вместе:

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

Должно быть достаточно читаемым, если вы знакомы с itertools , и без явного list вас даже есть результат в форме генератора.

Большинство из этих ответов будут работать только на одном уровне сглаживания. Для более полного решения попробуйте это (от 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) 

Мне нравится использовать «уменьшить» в этой ситуации (это то, что сделал сокращение!)

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

Для многоуровневого и читаемого кода:

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

Я не мог заставить это вписаться в одну строку (и оставаться читаемой, даже далеко)

Другое решение, использующее 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] 
  • Как можно изменить синтаксис индексации списка python?
  • Python: элементы списка подкачки в скопированном списке, не влияя на исходный список
  • Что делает синтаксис расширенного среза для отрицательных шагов?
  • Python struct.pack () для отдельных элементов в списке?
  • Удаление выбранных элементов из списка и из списка
  • Django: проверьте, есть ли значение в values_list с & без prefetch_related / select_related
  • Python: преобразование списка словарей в json
  • Zip с выводом списка вместо кортежа
  • Как превратить блок данных в ряд списков?
  • Распаковать список в середину кортежа
  • сжатие нескольких операторов if в python
  • Python - лучший язык программирования в мире.