web-dev-qa-db-ja.com

Pythonでネストされたリストを1次元のリストに変換するにはどうすればよいですか?

私は(私の知識では)配列を分割してそれらを結合し、さらにitertoolsを使用することからすべてを試しました:

_import itertools

def oneDArray(x):
    return list(itertools.chain(*x))
_

私が望む結果:

a)print oneDArray([1,[2,2,2],4]) == [1,2,2,2,4]

不思議なことに、それは

b)print oneDArray([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) == [1, 2, 3, 4, 5, 6, 7, 8, 9]

質問1)パートaを希望どおりに機能させるにはどうすればよいですか(ヒントはありますか?)

質問2)上記のコードがパートaではなくパートbで機能するのはなぜですか??

9
compski

リストを再帰的にループして、アイテムが反復可能かどうか(文字列も反復可能ですが、スキップするかどうか)を確認する必要があります。

itertools.chainはすべての項目を反復可能にする必要があるため[1,[2,2,2],4]では機能しませんが、14(整数)は反復可能ではありません。それがリストのリストであるため、それが2番目のもので機能した理由です。

>>> from collections import Iterable
def flatten(lis):
     for item in lis:
         if isinstance(item, Iterable) and not isinstance(item, basestring):
             for x in flatten(item):
                 yield x
         else:        
             yield item

>>> lis = [1,[2,2,2],4]
>>> list(flatten(lis))
[1, 2, 2, 2, 4]
>>> list(flatten([[1, 2, 3], [4, 5, 6], [7, 8, 9]]))
[1, 2, 3, 4, 5, 6, 7, 8, 9]

あらゆるレベルのネストで機能します。

>>> a = [1,[2,2,[2]],4]
>>> list(flatten(a))
[1, 2, 2, 2, 4]

他のソリューションとは異なり、これは文字列でも機能します。

>>> lis = [1,[2,2,2],"456"]
>>> list(flatten(lis))
[1, 2, 2, 2, '456']
10

python < 3を使用している場合は、次の操作を実行できます。

from compiler.ast import flatten
list = [1,[2,2,2],4]
print flatten(list)

python 3.0での手動の同等物は( この回答 から取得):

def flatten(x):
    result = []
    for el in x:
        if hasattr(el, "__iter__") and not isinstance(el, str):
            result.extend(flatten(el))
        else:
            result.append(el)
    return result

 print(flatten(["junk",["nested stuff"],[],[[]]]))  

リスト内包表記でも同じことができます。

list = [1,[2,2,2],4]
l = [item for sublist in list for item in sublist]

これは次と同等です:

l = [[1], [2], [3], [4], [5]]
result = []
for sublist in l:
    for item in sublist:
        result.append(item)

print(result)
11
Ewan

pythonのネストされたリストから単一のリストを作成するには、次のようにするだけです。

from functools import reduce

some_list = [[14], [215, 383, 87], [298], [374], [2,3,4,5,6,7]]
single_list = reduce(lambda x,y: x+y, some_list)
print(single_list)

出力:[14, 215, 383, 87, 298, 374, 2, 3, 4, 5, 6, 7]

1
Nabajeet Dhar

itertools.chain() 入力されたリストの各項目を繰り返し処理します(リンクしたドキュメントを参照してください)。整数を反復処理できないため、エラーが発生します。そのため、2番目の例では、リストにリストのみがあり、整数だけがないため、実際に整数が繰り返されることはありません。

それを機能させるには、再帰を使用できます。

>>> from collections import Iterable
>>> def flat(lst):
...     for parent in lst:
...         if not isinstance(i, Iterable):
...             yield parent
...         else:
...             for child in flat(parent):
...                 yield child
...
>>> list(flat(([1,[2,2,2],4]))
[1, 2, 2, 2, 4]
1
TerryA
0
SaintGermain

リストのリストの1つのレベルのみになる場合、最も簡単な解決策は次のとおりです。

lis = [1,[2,2,2],"456"]
output = []
for item in lis:
    if isinstance(item, (str, int, bool)):
        output.append(item)
    Elif isinstance(item, dict):
        for i in item.items():
            output.extend(i)
    else:
        output.extend(list(item))

私がextend(list(item))を使用した理由は、アイテム内にセットがあったとしても、問題が発生しないためです。これは、文字列、整数、ブール値、辞書、リスト、およびタプルとしてアイテムを処理します。

0
thiruvenkadam
old_list = [1,2,3,['a','b'],4,5,6,['c','d',[11,22,33,'aa','bb','cc',[111,222,333,['aaa','bbb','ccc',[1111,2222,['aaaa','bbbb',[11111,22222]]]]]],'e']]

new_list = []

def my_fun(temp_list):
    for ele in temp_list:
        if type(ele) == list:
            my_fun(ele)
        else:
            new_list.append(ele)


my_fun(old_list)
print old_list
print new_list

output:
old_list = [1, 2, 3, ['a', 'b'], 4, 5, 6, ['c', 'd', [11, 22, 33, 'aa', 'bb', 'cc', [111, 222, 333, ['aaa', 'bbb', 'ccc', [1111, 2222, ['aaaa', 'bbbb', [11111, 22222]]]]]], 'e']]
new_list = [1, 2, 3, 'a', 'b', 4, 5, 6, 'c', 'd', 11, 22, 33, 'aa', 'bb', 'cc', 111, 222, 333, 'aaa', 'bbb', 'ccc', 1111, 2222, 'aaaa', 'bbbb', 11111, 22222, 'e']

再帰を使用して、複数のネストされたリストを単一のスライスされたリストに変換します。

0
Abhishek

Itertoolsを使用しなくても実際には非常に簡単です。リストを反復処理するだけで、ループで別のリストが検出された場合は、ネストされたリストを反復処理するだけです。コードは次のとおりです。

def flatten(l):
    flatList = []
    for elem in l:
        # if an element of a list is a list
        # iterate over this list and add elements to flatList 
        if type(elem) == list:
            for e in elem:
                flatList.append(e)
        else:
            flatList.append(elem)
    return flatList


a = [1,[2,2,2],4]  # flatten(a) returns [1, 2, 2, 2, 4]
b =  [[1, 2, 3], [4, 5, 6], [7, 8, 9]] # flatten(b) returns [1, 2, 3, 4, 5, 6, 7, 8, 9]
0
Pawel Miech