2

こんにちは私はPythonの問題を抱えており、さまざまなレベルのネストを持つリストで、値2が含まれているリスト要素を数える必要があります。例えば:

my_list = [[2,3,2,2], [[2,1,2,1], [2,1,1]], [1,1,1]]

このリストには、最大3レベルのネストを含めることができますが、2レベルまたは1レベルの深さにすることもできます。

私はある種の動作をするコードを持っています:

count = 0
for i in my_list:
    if len(i) > 1:
        for x in i:
            if 2 in x:
                count += 1
    elif i == 2:
        count += 1

ただし、これは非常に醜いことを除けば、2である単一の要素を持つリストを持つ可能性を考慮していません。また、単一の要素を取得することもできませlen()int

私はリスト内包がこれを処理できるはずであることを知っていますが、私は潜在的な入れ子に対処する方法に固執しています。

どんな助けでも大歓迎です。

4

3 に答える 3

7

https://stackoverflow.com/a/2158532/367273flatten()のジェネレーターのバリアントを使用します

オリジナルは、イテラブルの任意にネストされた不規則な形状の構造からすべての要素を生成します。私のバリアント (以下) は、スカラーを生成する代わりに、最も内側の iterable を生成します。

from collections import Iterable

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

my_list = [[2,3,2,2], [[2,1,2,1], [2,1,1]], [1,1,1]]
print(sum(1 for el in flatten(my_list) if 2 in el))

あなたの例では、それは印刷され3ます。

于 2012-12-10T20:17:16.747 に答える
0

これを行う別の方法を次に示します。

small_list = [2]
my_list = [[2,3,2,2], [[2,1,2,1], [2,1,1]], [1,1,1]]
another_list = [[2,3,2,2], [[2,1,2,1], [2,1,1]], [1,1,1], 2]

from collections import Iterable 

def count_lists_w_two(x):
    if isinstance(x, Iterable) == False:
        return 0
    else:
        return (2 in x) + sum(count_lists_w_two(ele) for ele in x)

結果:

>>> count_lists_w_two(small_list)
1
>>> count_lists_w_two(my_list)
3
>>> count_lists_w_two(another_list)
4
于 2012-12-10T21:25:26.713 に答える
0

更新と最終回答:

私のソリューションは、ネストされたリストのリストを再帰します。リストに が含まれている場合2、カウントは 1 に設定されます。次に、サブリストのカウントの合計が追加されます。このアプローチは、以下の 2 番目の使用例のように、数値とリストを同じレベルで混在させることができる異種リストをサポートします。

import collections

def list_count(l):
    count = int(2 in l)
    for el in l:
        if isinstance(el, collections.Iterable):
            count += list_count(el)
    return count

いくつかのテスト ケースを次に示します。

my_list = [[2,3,2,2], [[2,1,2,1], [2,1,1]], [1,1,1]]
print = list_count(my_list)
# 3 is printed

my_list = [2, [2,3,2,2], [[2,1,2,1], [2,1,1]], [1,1,1]]
print = list_count(my_list)
# 4 is printed

@Akavallの答えは、これがワンライナーに折りたたまれる可能性があることを思い出させました。(しかし、これを行うと、SO で常に (通常は正当化された) 読みやすさの苦情が寄せられます。)

def list_count(l):
    return ( int(2 in l) +
        sum([list_count(el) for el in l 
            if isinstance(el, collections.Iterable)]) )

元の回答(元の質問が探していたものではありません)

更新: @NPE は、予想される結果が指定された後に回答を更新しました。彼の現在の答えは、元のポスターが望むように機能します。

@NPEの(元の)答えは近いですが、あなたは尋ねました:

値 2 を含むリスト要素を数える

あなたが必要として私が読んだもの:

my_list = [[2,3,2,2], [[2,1,2,1], [2,1,1]], [1,1,1]]
print(sum([1 for e in [flatten(sl) for sl in ml] if 2 in e]))

しかし、彼は探してい3ます。私のコードは、各最上位要素を反復処理し、2 が含まれている場合はそれをカウントするため、2 を生成しますが、それは彼が実際に望んでいることではありません。

于 2012-12-10T20:29:24.230 に答える