Тройные вложенные списки Python

У меня есть блок кода, который дает мне список с тремя вложенными в него списками:

my_list = [[['item1','item2']], [['item3', 'item4']]]

И я хотел бы сделать это:

my_list = [['item1','item2'], ['item3', 'item4']]

Любые предложения?

Ответ 1

Используйте понимание списка, чтобы выбрать один подзадачник из каждого подсписок:

>>> my_list = [item[0] for item in my_list]
[['item1', 'item2'], ['item3', 'item4']]

Также можно сгладить этот уровень вложенности с помощью sum, но это произойдет с ошибкой производительности, поскольку она имеет квадратичное время выполнения:

In [5]: my_list = [[[i, i+1]] for i in range(0, 10000, 2)]

In [6]: %timeit sum(my_list, [])
78.6 ms ± 2.15 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [7]: %timeit [x[0] for x in my_list]
187 µs ± 3.05 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [8]: 78600/187
Out[8]: 420.32085561497325

Это 420-кратное замедление для 5000-length my_list, которое вообще не очень длинное. Это еще хуже для более длинных списков.

Ответ 2

выполните следующие действия:

my_list = [j for i in my_list for j in i ]

Ответ 3

Простым, но эффективным способом является сглаживание вашего тройного вложенного списка с помощью itertools.chain.from_iterable:

>>> import itertools
>>> my_list = [[['item1','item2']],[['item3','item4']]]
>>> my_list = list(itertools.chain.from_iterable(my_list))
>>> my_list
[['item1', 'item2'], ['item3', 'item4']]

Что имеет сложность O(n) для списка размера n.

Ответ 4

my_list = list(map(lambda x :x[0], my_list))

Ответ 5

my_list = [[['item1','item2']],[['item3', 'item4']]]

Однострочный с list comprehension

my_list = [sub[0] for sub in my_list]

Вы также можете изменить my_list на месте:

my_list = [[['item1','item2']],[['item3', 'item4']]]

for i, sub in enumerate(my_list):
    my_list[i] = sub[0]

>>> my_list
[['item1', 'item2'], ['item3', 'item4']]
>>> 

Ответ 6

С map и operator.itemgetter:

map(operator.itemgetter(0), my_list)

В Python 3, который возвращает генератор. Если вам нужна list, оберните генератор внутри вызова list(...).

Ответ 7

Это так просто, как это, если вы хотите быстро исправить -

for i in range(len(my_list)):
    my_list[i]=my_list[i][0]

Ответ 8

python3

[[x], [y]] = my_list
print([x , y])

[['item1', 'item2'], ['item3', 'item4']]

Ответ 9

Быстрое исправление, если у вас есть аналогичная структура вложенных списков, рекурсивная функция ниже (или что-то подобное для других случаев) может обрабатывать любой уровень вложенности. Не измерял производительность, но он будет меньше по сравнению с другими решениями. Испытайте перед использованием. В python 2.7

def f(x):
    if hasattr(x[0], '__iter__'):
        return f(x[0])
    else:
        return x

>>> my_list = [[['item1','item2']], [['item3', 'item4']]]
>>> [f(elem) for elem in my_list]
[['item1', 'item2'], ['item3', 'item4']]
>>> my_list = [[[['item1','item2']]], [['item3', 'item4']],[[[['item5', 'item6']]]]]
>>> [f(elem) for elem in my_list]
[['item1', 'item2'], ['item3', 'item4'], ['item5', 'item6']]

Проверка hasattr() будет пропускать строки в python 2. Другие тесты, такие как iter(), могут рассматривать строки как iterable