2013-06-27 12 views
9

私はリストの理解を使用してリストを平坦化しようとしています。私のリストは、やや私は私が取得していますリストの内包を通して私のリストを平らにするために同じロジックを使用するとリストのリストのリストのリストを平滑化

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 

このコードを書いただけで、リストのこのリストの印刷、個々の項目について

[[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 

リストの理解度を使用してこのタイプのリストをフラット化するにはどうすればよいですか?

答えて

6
>>> from collections import Iterable 
>>> from itertools import chain 

ワンライナーのPython 3に存在していることに注意してください:

>>> 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'] 
+1

これは2.xを使っている質問者にはうってつけですが、3.xユーザーは2.xを使う代わりに 'str'を使うべきです'basestring'。 –

+0

@Ashwini要素が整数ではなくdict型の場合はどうすればよいですか? –

+0

@AnuragSharma小さな例ですか? –

3

あなたはできないことができる数値を反復しようとしています(したがって、エラーです)。

あなたは、Python 2.7使用している場合:

>>> from compiler.ast import flatten 
>>> flatten(l) 
[1, 2, 3, 4, 5, 6, 7, 8] 

をしかし、モジュールは廃止しないと、もはや

+1

タイプチェックリストは悪い考えです。これにより、柔軟性が大幅に低下します。 –

+1

もし 'l 'が' [[1,2,3]、[4,5,6]、7,888] 'ならば、最初の解は' [1,2,3,4,5,6,7、 8,8,8]。 – falsetru

+0

最初のビットを削除しましたが、私の他の解決策はPython 3ではうまくいきません。 – TerryA

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] 
+2

+1 'yield from'ステートメントについて知りませんでした。 –

3

ませ-1は通常の答えを与えていません。

StackOverflo w。

+1

彼のリストには反復不可能なオブジェクト、つまり整数が含まれているため、OPが提供するリストのコードは機能しません。 しかし、リスト内のすべての項目が反復可能なオブジェクトであれば、コードは機能します。 下記のコメントを参照してください。 – JDG

+1

それを指摘してくれてありがとう - 私は実際にはそれを取り乱し、グリップに来るために瞬間を見つける必要があります... – GreenAsJade

関連する問題