То же самое здесь: Конечно, это не будет обрабатывать произвольное вложение.

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

[('a', 'b'), ('c', 'd'), (('e', 'f'), ('h', 'i'))]

Я хочу превратить это в это:

[('a', 'b'), ('c', 'd'), ('e', 'f'), ('h', 'i')]

Какой самый питонский способ сделать это?

 L3viathan22 нояб. 2017 г., 11:06
Я не думаю, что это дубликат, так как он хочет сохранить пары
 GPhilo22 нояб. 2017 г., 11:06
 quamrana22 нояб. 2017 г., 11:14
Вы можете сгладить все это, а затем спарить остатки:zip(*[iter(L)]*2) из:stackoverflow.com/a/23286332/4834
 David Zhan Liu22 нояб. 2017 г., 11:08
да, я хочу сохранить пары. Я легко могу сделать это с помощью некоторых операторов if в цикле for, но мне интересно, есть ли лучший способ, используя списки или итераторы
 GPhilo22 нояб. 2017 г., 11:06
Действительно, я убрал флаг

Ответы на вопрос(3)

Настроитьканонический рецепт только в том случае, если в значении есть кортежи:

def flatten(l):
    for el in l:
        if isinstance(el, tuple) and any(isinstance(sub, tuple) for sub in el):
            for sub in flatten(el):
                yield sub
        else:
            yield el

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

>>> sample = [('a', 'b'), ('c', 'd'), (('e', 'f'), ('h', 'i'))]
>>> list(flatten(sample))
[('a', 'b'), ('c', 'd'), ('e', 'f'), ('h', 'i')]

Однострочное решение будет использоватьitertools.chain:

>>> l = [('a', 'b'), ('c', 'd'), (('e', 'f'), ('h', 'i'))]
>>> from itertools import chain
>>> [*chain.from_iterable(x if isinstance(x[0], tuple) else [x] for x in l)]
[('a', 'b'), ('c', 'd'), ('e', 'f'), ('h', 'i')]
 Martijn Pieters♦22 нояб. 2017 г., 11:16
То же самое здесь: Конечно, это не будет обрабатывать произвольное вложение.
Решение Вопроса

в одну строку, используя понимание списка:

l = [('a', 'b'), ('c', 'd'), (('e', 'f'), ('h', 'i'))]

result = [z for y in (x if isinstance(x[0],tuple) else [x] for x in l) for z in y]

print(result)

выходы:

[('a', 'b'), ('c', 'd'), ('e', 'f'), ('h', 'i')]

это искусственное создание списка, если элемент не является кортежем кортежей, тогда сглаживание всех делает свою работу. Чтобы избежать создания единого списка элементов[x], (x for _ in range(1)) может также сделать работу (хотя это кажется неуклюжим)

Ограничение: не обрабатывает более 1 уровня вложенности. В этом случае должно быть закодировано более сложное / рекурсивное решение.

 Martijn Pieters♦22 нояб. 2017 г., 11:15
Это не будет обрабатывать произвольное вложение, конечно.
 Jean-François Fabre22 нояб. 2017 г., 11:16
@MartijnPieters ваше рекурсивное решение - единственное, которое может сделать это, и у вас есть мой UV. Кстати(x for _ in range(1)) хорошо, чтобы избежать создания[x] список или есть лучшие способы?

Ваш ответ на вопрос