Преобразование списка кортежей в простой плоский список - программирование
Подтвердить что ты не робот

Преобразование списка кортежей в простой плоский список

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

Скажем, у меня есть следующий список кортежей:

[(1,2), (1,3), (1,4), (1,5), (1,6)]

Я пытаюсь преобразовать его в простой список, как показано ниже:

[1,2,1,3,1,4,1,5,1,6]

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

Есть ли какие-нибудь быстрые и эффективные способы сделать это без фактического итерации через исходный список кортежей, или есть ли встроенная функция/метод для этого?

4b9b3361

Ответ 1

lst = [(1,2), (1,3), (1,4), (1,5), (1,6)]

import itertools
list(itertools.chain(*lst))
# [1, 2, 1, 3, 1, 4, 1, 5, 1, 6]

В качестве альтернативы:

[e for l in lst for e in l]
# [1, 2, 1, 3, 1, 4, 1, 5, 1, 6]

Ответ 2

"В основном, какой из них быстрее? Используя модуль" itertools "или используя понимание списка? Я в основном пытаюсь улучшить скорость вычислений здесь. - @davidadamojr

Я делал несколько тестов, и я обнаружил, что код ниже на самом деле быстрее.

list_ = [(1, 2), (1, 3), (1, 4), (1, 5), (1, 6)]
list(sum(list_, ()))

Кто-то исправит меня, если я ошибаюсь.

Ниже приведены некоторые тесты.

>>> list_ = [(1, 2), (1, 3), (1, 4), (1, 5), (1, 6)]
>>> 
>>> operation_1 = lambda: [tuple_item for tuple_ in list_ for tuple_item in tuple_]
>>> def operation_2 ():
        final_list = []
        for tuple_ in list_:
            for tuple_item in tuple_:
                final_list.append(tuple_item)
        return final_list

>>> operation_3 = lambda: reduce(list.__add__, map(list, list_))
>>> def operation_4 ():
        import itertools
        return list(itertools.chain(*list_))

>>> operation_5 = lambda: list(sum(list_, ()))
>>> 
>>> operation_1()
[1, 2, 1, 3, 1, 4, 1, 5, 1, 6]
>>> operation_2()
[1, 2, 1, 3, 1, 4, 1, 5, 1, 6]
>>> operation_3()
[1, 2, 1, 3, 1, 4, 1, 5, 1, 6]
>>> operation_4()
[1, 2, 1, 3, 1, 4, 1, 5, 1, 6]
>>> operation_5()
[1, 2, 1, 3, 1, 4, 1, 5, 1, 6]
>>> 
>>> import timeit
>>> 
>>> print('operation_1 completed in %s seconds.' % (timeit.timeit(operation_1)))
operation_1 completed in 1.57890490223 seconds.
>>> print('operation_2 completed in %s seconds.' % (timeit.timeit(operation_2)))
operation_2 completed in 2.90350501659 seconds.
>>> print('operation_3 completed in %s seconds.' % (timeit.timeit(operation_3)))
operation_3 completed in 5.08437990236 seconds.
>>> print('operation_4 completed in %s seconds.' % (timeit.timeit(operation_4)))
operation_4 completed in 3.85125378138 seconds.
>>> print('operation_5 completed in %s seconds.' % (timeit.timeit(operation_5)))
operation_5 completed in 1.2623826489 seconds.

Ответ 3

Используйте chain.from_iterable, так как он избегает ненужной распаковки "все в один раз" (что приводит к избыточному потреблению памяти), лениво продвигаясь по списку:

>>> import itertools
>>> L = [(1,2), (1,3), (1,4), (1,5), (1,6)]
>>> list(itertools.chain.from_iterable(L))
[1, 2, 1, 3, 1, 4, 1, 5, 1, 6]

Ответ 4

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

>>> l = [(1,2), (1,3), (1,4), (1,5), (1,6)] 
>>> reduce(list.__add__,map(list,l))
[1, 2, 1, 3, 1, 4, 1, 5, 1, 6]