从一组值中匹配列表

时间:2019-01-11 17:13:03

标签: python python-2.7

我正在使用python 2.7,并且具有以下列表:

<input type="file" id= "add2" multiple>

然后我有一个像这样的字典:

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

我正在尝试寻找一种方法来搜索值,但它需要与list1中的两个条目匹配

我有以下代码,但是它将匹配一个然后爆发,我知道为什么会爆发,但是我想不出一种方法来强制它在两个条目上都匹配然后爆发。我知道我可以使用all()来完全匹配所有内容,但是我只是想看看这两个条目是否都存在。

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

目标是仅输出GI2 / 1/1和GI2 / 1/2,因为GI2 / 1/3在两个条目上都不匹配

4 个答案:

答案 0 :(得分: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

(如果要列出所有符合约束条件的条目,只需删除该中断)

答案 1 :(得分:0)

您可以简单地使用str.startswith(如果您不在乎位置,可以坚持使用in),然后将其与allany结合使用:

代码

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

我认为这两种方法都是可以理解的:您只要看看它们,便知道它们的作用

希望对您有所帮助!

答案 2 :(得分:-1)

您可以遍历list1以在my_dict中生成键集,其中任何字符串子列表都包含list1中的给定关键字,然后使用{{1 }}函数通过设置交集产生所需的输出:

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

答案 3 :(得分:-2)

您可以创建一个新的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 val == set(list1)]
#['GI2/1/1', 'GI2/1/2']

这绝对可以在一行中完成,但是我认为通过两步查看正在发生的事情可能会更容易。我将所有匹配项存储在一个列表中,该列表变成set(删除重复项),然后将其与list1中所需的匹配项进行比较。

编辑:如@blhsing所指出,python中的set是无序的。我不是用list的值来制作result,而是用set的值来制作list1,因为我不认为OP会在{{1 }}。

另一种方法是使用list1并检查所有项目。

all

编辑#2:由于OP在注释中的要求。这是另一种可能的方式。 (由@JosuéCortina的回答所激励)。

result = {key: set([item for item in list1 for things in val if item in things]) for key, val in my_dict.iteritems()}

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

如果我们只有列表列表,并且希望布尔值查看子列表是否与我们要查找的内容匹配,那么上面的方法可能是一种解决方案。