У меня есть блок кода, который дает мне список с тремя вложенными в него списками:
my_list = [[['item1','item2']], [['item3', 'item4']]]
И я хотел бы сделать это:
my_list = [['item1','item2'], ['item3', 'item4']]
Любые предложения?
У меня есть блок кода, который дает мне список с тремя вложенными в него списками:
my_list = [[['item1','item2']], [['item3', 'item4']]]
И я хотел бы сделать это:
my_list = [['item1','item2'], ['item3', 'item4']]
Любые предложения?
Используйте понимание списка, чтобы выбрать один подзадачник из каждого подсписок:
>>> 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
, которое вообще не очень длинное. Это еще хуже для более длинных списков.
выполните следующие действия:
my_list = [j for i in my_list for j in i ]
Простым, но эффективным способом является сглаживание вашего тройного вложенного списка с помощью 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
.
my_list = list(map(lambda x :x[0], my_list))
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']]
>>>
С map
и operator.itemgetter
:
map(operator.itemgetter(0), my_list)
В Python 3, который возвращает генератор. Если вам нужна list
, оберните генератор внутри вызова list(...)
.
Это так просто, как это, если вы хотите быстро исправить -
for i in range(len(my_list)):
my_list[i]=my_list[i][0]
python3
[[x], [y]] = my_list
print([x , y])
[['item1', 'item2'], ['item3', 'item4']]
Быстрое исправление, если у вас есть аналогичная структура вложенных списков, рекурсивная функция ниже (или что-то подобное для других случаев) может обрабатывать любой уровень вложенности. Не измерял производительность, но он будет меньше по сравнению с другими решениями. Испытайте перед использованием. В 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