16

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

リスト内包表記を使用して、このタイプのリストのリストをフラット化するにはどうすればよいですか?

4

5 に答える 5

13
>>> 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']
于 2013-06-27T09:04:36.417 に答える
3

ジェネレーターを使用した代替ソリューション:

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]
于 2013-06-27T09:18:40.880 に答える