値の集合からのリスト内でのマッチング

私はPython 2.7を使っています、そして私は以下のリストを持っています:

list1 = ['switchport port-security maximum', 'switchport port-security aging']

そして、私はこのような辞書があります。

my_dict = {}

my_dict["GI2/1/1"] = [
'switchport port-security maximum 10', 
'switchport port-security maximum 3 vlan access', 
'switchport port-security maximum 1 vlan voice', 
'switchport port-security aging time 25', 
'switchport port-security aging type inactivity', 
'switchport port-security'
]

my_dict["GI2/1/2"] = [
'switchport port-security maximum 5', 
'switchport port-security maximum 5 vlan access', 
'switchport port-security maximum 3 vlan voice', 
'switchport port-security aging time 20', 
'switchport port-security aging type inactivity', 
'switchport port-security'
]


my_dict["GI2/1/3"] = [
'switchport port-security maximum 10', 
'switchport port-security maximum 3 vlan access', 
'switchport port-security maximum 1 vlan voice',  
'switchport port-security'
]

私は値を検索することができる方法を見つけようとしていますが、それはlist1の両方のエントリで一致する必要があるでしょう

私は次のコードを持っていますが、それは1つにマッチし、そしてブレークアウトするでしょう。 all()を使用してすべてを正確に一致させることができますが、両方のエントリが存在するかどうかを確認したいのですが。

for name, val in my_dict.iteritems():
    for v in val:
        for i in list1:
            if i in v:
                print name
                break

GI2/1/3は両方のエントリで一致しないため、目標はGI2/1/1とGI2/1/2のみを出力することです

0
break list1 ループから抜け出しただけで、外側のループで続行する必要があります。
追加された 著者 Barmar,
予想される出力は何ですか? 「値を検索しますが、list1の両方のエントリで一致する必要がある」とはどういう意味ですか。
追加された 著者 blhsing,
Josueはその通りです、ただ休憩を外してください。
追加された 著者 HectorIX,
break を削除するだけでうまくいきますか?
追加された 著者 Josué Cortina,
GI2/1/3とGI2/1/2のみが出力されます
追加された 著者 Mr39,

5 答え

list1 のエントリが any に一致する場合は、印刷中です。すべてのエントリに一致する場合にのみ印刷します。すべて all() を使用できます。関数:

for name, val in my_dict.iteritems():
    for v in val:
        if all(i in v for i in list1):
            print name
            break
1
追加された
これは私に何も出力を与えない
追加された 著者 Josué Cortina,

list1 を繰り返し処理して my_dict にキーのセットを生成することができます。ここでは、文字列のサブリストのいずれかに list1 の指定キーワードが含まれます次に reduce 関数を使用して集合交差を介して目的の出力を生成します。

reduce(set.intersection, ({n for n, l in my_dict.iteritems() if any(k in i for i in l)} for k in list1))

これは

set(['GI2/1/1', 'GI2/1/2'])
1
追加された
私はこれがかなり読めなくて有益であると思います
追加された 著者 Josué Cortina,

結果をキャプチャする新しい dict を作成できます。

result = {key: set([item for item in list1 for things in val if item in things]) for key, val in my_dict.iteritems()}
#{'GI2/1/1': {'switchport port-security maximum', 'switchport port-security aging'}, 'GI2/1/2': {'switchport port-security maximum', 'switchport port-security aging'}, 'GI2/1/3': {'switchport port-security maximum'}}

result = [key for key, val in result.iteritems() if list(val) == list1]
#['GI2/1/1', 'GI2/1/2']

これは間違いなく1行で実行できますが、2つのステップで何が起こっているのかを確認するほうが簡単な場合があると思いました。すべての一致を set に変換されたリストに格納し、それを list1 の目的の一致と比較します。

0
追加された

単に<コード> str.startswith を使用し、それを<コード> all および<コード> any と組み合わせることができます。

コード

<コード>for name, val in my_dict.iteritems():
    if all(any(v.startswith(l) for v in val) for l in list1):
        print name

正規表現を使用できますが、やりすぎになる可能性があります。

コード

<コード>import re

regexps = [re.compile(i) for i in list1]

for name, val in my_dict.iteritems():
    if all(any(regexp.match(v) for v in val) for regexp in regexps):
        print name

出力

<コード>GI2/1/1
GI2/1/2

I think both of this methods are pretty understandable: you know what they do just having a look at them

これがお役に立てば幸いです。

0
追加された

私があなたが望むものを理解したかどうかわからないが、何かが好きですか?

def cont(l,s):
    for i in l:
        if s in i:
            return True
    return False

for name, val in my_dict.iteritems():
        happy=True
        for i in list1:
            if not cont(val,i):
                happy=False
        if happy:
            print name
            break

(制約に一致するすべてのエントリーをリストしたい場合は、単に切れ目を削除してください)

0
追加された