@Diolorca

Как распаковать вложенный список?

Здравствуйте!
Как распаковать вложенный список?

Есть такой список:
posl = ['Один',  'Два',  'Три',  ['Четыре',  'Пять',  'Шесть' ], 'Семь']


Нужно сделать так:
posl = ['Один',  'Два',  'Три',  'Четыре',  'Пять',  'Шесть' , 'Семь']


Варианты вроде:
new_list = [item for sublist in posl for item in sublist]


Или
chained = []
while li:
     chained.extend(posl.pop(0))


Дают результат:

posl = ['О', 'д', 'и', 'н',  'Д', 'в', 'а',  'Т', 'р', 'и',  'Четыре',  'Пять',  'Шесть' , 'С', 'е', 'м', 'ь']

Что не то, что нужно

Есть еще:
from itertools import chain

list(chain.from_iterable(posl))


Но у меня не работает.
  • Вопрос задан
  • 136 просмотров
Решения вопроса 6
ipatiev
@ipatiev
Потомок старинного рода Ипатьевых-Колотитьевых
Наверное, надо проверять элемент исходного списка, является ли он списком, и только тогда распаковывать?
Если уровень вложенности у нас один, то так и написать
chained = []
for item in posl:
    if isinstance(item, list):
        for subitem in item:
            chained.append(subitem)
    else:
        chained.append(item)

Это будет самый кондовый алгоритм. Задачу можно реализовать и короче, и оптимальнее. Но при изучении программирования надо сначала научиться составлять самому простейшие алгоритмы и их реализовывать, а не просто пытаться использовать по очереди какие-то магические заклинания - авось какое-то сработает. А если не сработает - то идти на Хабр, чтобы тебе его написали.
Любой красивый код следует применять только тогда, когда ты понимаешь, как он работает, что делает внутри. А если не понимаешь, то лучше сначала разобраться, реализовать тот же алгоритм руками. Иначе ты будешь не программист, а обезьяна с гранатой.

Если вложенность неограниченная, то придется познакомиться с таким понятием, как рекурсия.
Ответ написан
Комментировать
sergey-gornostaev
@sergey-gornostaev Куратор тега Python
Седой и строгий
from collections import abc

def flatten(iterable):
    for item in iterable:
        if isinstance(item, (str, bytes)):
            yield item
        elif isinstance(item, abc.Sequence):
            yield from flatten(item)
        else:
            yield item


data = ['Один',  'Два',  'Три',  ['Четыре',  'Пять',  'Шесть' ], 'Семь']

flat_data = list(flatten(data))
Ответ написан
Комментировать
fox_12
@fox_12 Куратор тега Python
Расставляю биты, управляю заряженными частицами
Обход рекурсией:
posl = ['Один',  'Два',  'Три',  ['Четыре',  'Пять',  'Шесть', ['Семь', 'Восемь', ['Девять']] ], 'Десять']

def unpack_list(somelist):
    res = []
    def to_flat(item):
        if isinstance(item, list):
            for im in item:
                to_flat(im)
        else:
            res.append(item)
    return to_flat(somelist)

print(unpack_list(posl))

# ['Один', 'Два', 'Три', 'Четыре', 'Пять', 'Шесть', 'Семь', 'Восемь', 'Девять', 'Десять']
Ответ написан
Комментировать
phaggi
@phaggi Куратор тега Python
лужу, паяю, ЭВМы починяю
data = ['Один',  'Два',  'Три',  ['Четыре',  'Пять',  'Шесть' ], 'Семь']
print(str(data).replace('[', '').replace(']', '').replace("'",'').split(','))
Ответ написан
Комментировать
@newPsevdonim
Python разработчик
Вы можете определять тип элемента к которому обращаетесь и в случае если это список распаковывать его.

Тип в условном операторе можно определить с помощью isinstance(). Допустим как--нибудь так:

new_posl = []
for i in posl:
    if isinstance(i, list):
        for j in i:
            new_posl.append(j)
    else:
         new_posl.append(i)
Ответ написан
Комментировать
@PavelMos
для одного уровня вложенности
pos1 = ['Один',  'Два',  'Три',  ['Четыре',  'Пять',  'Шесть' ], 'Семь']
pos2 = []
for i in pos1:
    if type(i) != list:
        pos2 += [i] # += для списков это exndend, тут добавляется строка как один элемент, а не как список символов строки, и поэтому в примере получалось posl = ['О', 'д', 'и', 'н',  'Д', 'в', 'а',  'Т', 'р', 'и', 
    else:
        pos2 += i # extend сразу последовательность как следующий элемент как список, то есть список слов, т.к. он и есть список слов
# то есть += или extend слово / строка - добавит слово как список символов, 
# а += или extend [..] добавит слово или строку как отдельный элемент 
# см про append и extend
print (pos2)
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
aRegius
@aRegius
Python Enthusiast
list(collapse(iterable))
more_itertools.collapse
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы