В Sqlite команда «select..from» возвращает результат «output», который печатает (в python):
>>print output
[(12.2817, 12.2817), (0, 0), (8.52, 8.52)]
Кажется, это список кортежей. Я хотел бы либо преобразовать «вывод» в простой одномерный массив (я думаю, это список в Python):
[12.2817, 12.2817, 0, 0, 8.52, 8.52]
или матрица 2x3:
12.2817 12.2817
0 0
8.52 8.52
для чтения через "output [i] [j]"
Команда flatten не работает для первого варианта, а второй я понятия не имею ... :)
Не могли бы вы мне намекнуть? Что-то быстрое было бы замечательно, поскольку реальные данные намного больше (вот только простой пример).
[(12.2817, 12.2817), (0, 0), (8.52, 8.52)]
это уже матрица 3х2 !? или я что-то упустил?[item for sublist in output for item in sublist]
отлично работает и имеет то преимущество, что ваши внутренние кортежи также могут быть списками; в общем, любая комбинация внутренних и внешних повторяемых работОтветы:
Безусловно, самое быстрое (и самое короткое) решение опубликовано:
list(sum(output, ()))
Примерно на 50% быстрее, чем
itertools
раствор, и примерно на 70% быстрее, чемmap
раствор.источник
list(output[0]+output[1]+output[2])
дает желаемый результат ноlist(sum(output))
нет. Почему? Какое «волшебство» делает ()?sum(sequence[, start])
: сумма добавляет,start
который по умолчанию,0
а не просто начиная с,sequence[0]
если он существует, а затем добавляет остальные элементы. Извините за беспокойство.sum
для объединения последовательностей, это приводит к квадратичному алгоритму времени. Действительно,sum
функция будет жаловаться, если вы попытаетесь сделать это со строками!Подход к пониманию списка, который работает с итерабельными типами и работает быстрее, чем другие методы, показанные здесь.
flattened = [item for sublist in l for item in sublist]
l
список для сглаживания (вызывается вoutput
случае OP)timeit тесты:
l = list(zip(range(99), range(99))) # list of tuples to flatten
Понимание списка
[item for sublist in l for item in sublist]
timeit result = 7,67 мкс ± 129 нс на цикл
Список метод расширения ()
flattened = [] list(flattened.extend(item) for item in l)
timeit result = 11 мкс ± 433 нс на цикл
сумма ()
list(sum(l, ()))
timeit result = 24,2 мкс ± 269 нс на цикл
источник
В Python 2.7 и во всех версиях Python3 вы можете использовать
itertools.chain
для сглаживания списка итераций. Либо с*
синтаксисом, либо с методом класса.>>> 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] >>> list(itertools.chain.from_iterable(t)) [1, 2, 3, 4, 5, 6]
источник
Обновление : сглаживание с использованием расширения, но без понимания и без использования списка в качестве итератора (самый быстрый)
После проверки следующего ответа на этот вопрос, который обеспечил более быстрое решение через понимание списка,
dual for
я немного подправил, и теперь он работает лучше, сначала выполнение list (...) перетаскивало большой процент времени, а затем меняло список понимание простой петли также побрило немного больше.Новое решение:
l = [] for row in output: l.extend(row)
Старший:
Сглаживание с картой / расширением:
l = [] list(map(l.extend, output))
Сглаживание с пониманием списка вместо карты
l = [] list(l.extend(row) for row in output)
некоторое время для нового расширения и улучшения, полученного путем простого удаления списка (...) для [...]:
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
источник
использовать
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]
источник
>>> 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] >>>
вы можете легко перейти от списка кортежей к одному списку, как показано выше.
источник
Или вы можете сгладить список следующим образом:
reduce(lambda x,y:x+y, map(list, output))
источник
reduce(lambda x,y:x+y, output)
похоже, работает с прямым преобразованием в длинный кортеж (который можно преобразовать в список). Зачем использоватьmap(list, output)
внутриreduce()
звонка? Возможно, это больше соответствует тому факту, что кортежи неизменяемы, списки изменяемы .Это то,
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]
источник