Преобразуйте «список кортежей» в плоский список или матрицу

С Sqlite, "выберите ... из" Команда возвращает результаты «output», которые выводятся (на python):

>>print output
[(12.2817, 12.2817), (0, 0), (8.52, 8.52)]

Кажется, это список кортежей. Я хотел бы либо преобразовать & quot; вывод & quot; в простом одномерном массиве (= список в Python, я думаю):

[12.2817, 12.2817, 0, 0, 8.52, 8.52]

или матрица 2х3:

12.2817 12.2817
0          0 
8.52     8.52

быть прочитанным через «output [i] [j]»

Команда flatten не выполняет работу для первого варианта, и я понятия не имею для второго ... :)

Не могли бы вы дать мне подсказку? Что-то быстрое было бы здорово, так как реальные данные намного больше (вот простой пример).

 Joel Cornett17 мая 2012 г., 11:26
Увидетьthis question
 Kyss Tao05 мая 2013 г., 20:59
[item for sublist in output for item in sublist] отлично работает и имеет то преимущество, что ваши внутренние кортежи также могут быть списками; в более общем смысле любая комбинация внутренних и внешних повторяемых работ
 mouad17 мая 2012 г., 11:30
для функции проверки сглаживания рецептов модуля itertools уже есть пример функции сглаживания:docs.python.org/library/itertools.html#recipes
 mouad17 мая 2012 г., 11:24
[(12.2817, 12.2817), (0, 0), (8.52, 8.52)] это уже матрица 3х2!? или я что то пропустил?

Ответы на вопрос(9)

Подход к пониманию списков, который работает с типами Iterable и работает быстрее, чем другие методы, показанные здесь.

flattened = [item for sublist in l for item in sublist]

l это список, чтобы сгладить (называетсяoutput в случае с OP)

timeit tests:
l = list(zip(range(99), range(99)))  # list of tuples to flatten
List comprehension
[item for sublist in l for item in sublist]

результат timeit = 7.67 & # xB5; s & # xB1; 129 нс за цикл

List extend() method
flattened = []
list(flattened.extend(item) for item in l)

результат timeit = 11 & # xB5; s & # xB1; 433 нс за цикл

sum()
list(sum(l, ()))

результат timeit = 24,2 & # xB5; s & # xB1; 269 нс за цикл

 20 нояб. 2018 г., 18:00
Я немного изменил решение .extend и теперь работаю немного лучше. проверить это в свое время, чтобы сравнить
 16 авг. 2018 г., 08:36
Я должен был использовать это в большом наборе данных, метод понимания списка был самым быстрым!

Это то, чтоnumpy было сделано как для структур данных, так и с точки зрения скорости.

import numpy as np

output = [(12.2817, 12.2817), (0, 0), (8.52, 8.52)]
output_ary = np.array(output)   # this is your matrix 
output_vec = output_ary.ravel() # this is your 1d-array

В случае произвольных вложенных списков (на всякий случай):

def flatten(lst):
    result = []
    for element in lst: 
        if hasattr(element, '__iter__'):
            result.extend(flatten(element))
        else:
            result.append(element)
    return result

>>> flatten(output)
[12.2817, 12.2817, 0, 0, 8.52, 8.52]

использованиеitertools цепь:

>>> import itertools
>>> list(itertools.chain.from_iterable([(12.2817, 12.2817), (0, 0), (8.52, 8.52)]))
[,12.2817, 12.2817, 0, 0, 8.52, 8.52]

Или вы можете сгладить список следующим образом:

reduce(lambda x,y:x+y, map(list, output))

Другая опция быстрее, чем опция sum для больших массивов:

Сглаживание с картой / расширение:

l = []
list(map(l.extend, output))

Сглаживание с пониманием списка вместо карты (быстрее)

l = []
list(l.extend(row) for row in output)

Update: Выравнивание с использованием расширения, но без понимания и без использования списка в качестве итератора (самый быстрый)

После проверки следующего ответа на этот вопрос, который обеспечил более быстрое решение через понимание списка сdual for Я сделал небольшую настройку, и теперь она работает лучше: сначала выполнение списка (...) тянуло большой процент времени, а затем изменило понимание списка для простого цикла, побрившего немного больше. Окончательное решение:

l = []
for row in output: l.extend(row)

Некоторое время для нового расширения и улучшения можно получить, просто удалив список (...) для [...]:

import timeit
t = timeit.timeit
o = "output=list(zip(range(1000000000), range(10000000))); l=[]"
steps_ext = "for row in output: l.extend(row)"
steps_ext_old = "list(l.extend(row) for row in output)"
steps_ext_remove_list = "[l.extend(row) for row in output]"
steps_com = "[item for sublist in output for item in sublist]"

print("new extend:      ", t(steps_ext, setup=o, number=10))
print("old extend w []: ", t(steps_ext_remove_list, setup=o, number=10))
print("comprehension:   ", t(steps_com, setup=o, number=10,))
print("old extend:      ", t(steps_ext_old, setup=o, number=10))

>>> new extend:       4.502427191007882
>>> old extend w []:  5.281140706967562
>>> comprehension:    5.54302118299529
>>> old extend:       6.840151469223201    
 25 сент. 2017 г., 01:48
это правильное решение для больших массивов
>>> flat_list = []
>>> nested_list = [(1, 2, 4), (0, 9)]
>>> for a_tuple in nested_list:
...     flat_list.extend(list(a_tuple))
... 
>>> flat_list
[1, 2, 4, 0, 9]
>>> 

Вы можете легко перейти от списка кортежей к одному списку, как показано выше.

На сегодняшний день самое быстрое (и самое короткое) решение опубликовано:

list(sum(output, ()))

Примерно на 50% быстрее, чемitertools решение, и примерно на 70% быстрее, чемmap решение.

 12 апр. 2018 г., 01:19
@ juanpa.arrivillaga: согласился. Есть очень мало случаев использования, где это было бы предпочтительным.
 05 мая 2013 г., 20:39
@ Джоэл, хорошо, но мне интересно, как это работает?list(output[0]+output[1]+output[2]) дает желаемый результат, ноlist(sum(output)) не. Зачем? Что такое "магия" () делает?
 22 мая 2018 г., 23:30
Да, быстро, но совершенно тупо. Вы должны оставить комментарий о том, что он на самом деле делает :(
 05 мая 2013 г., 20:44
Хорошо, я должен был прочитать руководствоg, Похоже на тоsum(sequence[, start]): сумма добавляетstart который по умолчанию0 а не только начиная сsequence[0] если он существует, а затем добавление остальных элементов. Извините, что беспокою вас.
 12 апр. 2018 г., 00:42
Это хорошо известный анти-паттерн: не используйтеsum чтобы объединить последовательности, это приводит к алгоритму квадратичного времени. Действительно,sum Функция будет жаловаться, если вы попытаетесь сделать это со строками!

В Python 3 вы можете использовать* синтаксис для выравнивания списка итераций:

>>> t = [ (1,2), (3,4), (5,6) ]
>>> t
[(1, 2), (3, 4), (5, 6)]
>>> import itertools
>>> list(itertools.chain(*t))
[1, 2, 3, 4, 5, 6]
>>> 
 20 апр. 2016 г., 23:05
работает на Python 2.7.6 тоже!

Ваш ответ на вопрос