Сгладить список списков через понимание списка
Я пытаюсь сгладить список, используя понимание списка в python. Мой список несколько похож на
[[1, 2, 3], [4, 5, 6], 7, 8]
только для печати, а затем отдельный элемент в этом списке списка Я написал этот код
def flat(listoflist):
for item in listoflist:
if type(item) != list:
print item
else:
for num in item:
print num
>>> flat(list1)
1
2
3
4
5
6
7
8
Затем я использовал ту же логику, чтобы сгладить список из-за понимания списка. Я получаю следующую ошибку.
list2 = [item if type(item) != list else num for num in item for item in list1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
Как я могу сгладить этот список списков, используя использование списка?
Ответы
Ответ 1
>>> from collections import Iterable
>>> from itertools import chain
Однострочник:
>>> list(chain.from_iterable(item if isinstance(item,Iterable) and
not isinstance(item, basestring) else [item] for item in lis))
[1, 2, 3, 4, 5, 6, 7, 8]
читаемая версия:
>>> def func(x): #use `str` in py3.x
... if isinstance(x, Iterable) and not isinstance(x, basestring):
... return x
... return [x]
...
>>> list(chain.from_iterable(func(x) for x in lis))
[1, 2, 3, 4, 5, 6, 7, 8]
#works for strings as well
>>> lis = [[1, 2, 3], [4, 5, 6], 7, 8, "foobar"]
>>> list(chain.from_iterable(func(x) for x in lis))
[1, 2, 3, 4, 5, 6, 7, 8, 'foobar']
Использование вложенного списка: (медленнее по сравнению с itertools.chain
):
>>> [ele for item in (func(x) for x in lis) for ele in item]
[1, 2, 3, 4, 5, 6, 7, 8, 'foobar']
Ответ 2
Никто не дал обычный ответ:
def flat(l):
return [y for x in l for y in x]
В StackOverflow есть дубликаты этого вопроса.
Ответ 3
Вы пытаетесь выполнить итерацию по числу, которое вы не можете сделать (отсюда и ошибка).
Если вы используете python 2.7:
>>> from compiler.ast import flatten
>>> flatten(l)
[1, 2, 3, 4, 5, 6, 7, 8]
Но обратите внимание, что модуль теперь устарел и больше не существует в Python 3
Ответ 4
Альтернативное решение с использованием генератора:
import collections
def flatten(iterable):
for item in iterable:
if isinstance(item, collections.Iterable) and not isinstance(item, str): # `basestring` < 3.x
yield from item # `for subitem in item: yield item` < 3.3
else:
yield item
>>> list(flatten([[1, 2, 3], [4, 5, 6], 7, 8]))
[1, 2, 3, 4, 5, 6, 7, 8]