在集合列表中查找具有快速性能的模式

时间:2019-01-04 13:45:32

标签: python

设置

给出集合列表:

mylist = [{'a','the'}, {'red', 'brown', 'white'}, {'dog', 'cat'}]

我需要验证mylist中是否包含元素列表中的任何给定列表

pattern_match(['a', 'red', 'dog'], mylist) # True

pattern_match(['a', 'grey', 'cat'], mylist) # False, because of 'grey'

原始解决方案

我将pattern_match表示为

def pattern_match(sequence, patterns):
    if len(sequence) == len(patterns):
        return all([sequence[i] in patterns[i] for i in range(len(patterns))])
    else:
        return False

这对于检查像['a','brown','dog']这样的单个序列非常有效,并且代码清晰易懂

检查许多序列的问题

我需要及时对相当长的一组列表中的['a','brown','dog']之类的大量序列进行此操作

给予

mylist = [{'a','the'}, {'red', 'brown', 'white'}, {'dog', 'cat'}]
mysequences = [['a','brown','dog'], ['the','yellow','horse'], ...] # len(mysequences) is very high

考虑性能的最佳方法是什么,以达到与以下代码相同的结果:

[pattern_match(seq, mylist) for seq in mysequences] # yields [True, False, ...]

2 个答案:

答案 0 :(得分:4)

您可以在pattern_match函数中优化性能:

def pattern_match(sequence, patterns):
    if len(sequence) == len(patterns):
        return all(item in my_set for item, my_set in zip(sequence, patterns))
    else:
        return False

通过摆脱列表理解,我们可以在第一次检查失败后停止检查。

答案 1 :(得分:1)

我建议这样的事情:

def pattern_match(sequence, patterns):
    seq = set(sequence)
    u = set()
    for pattern in patterns:
        u.update(pattern) #includes pattern members in u
    return seq.issubset(u) # checks if sequence is subset of u

issubset()update()已记录在here中。但是根据使用情况,您可能需要在函数外部构造u并将最终值传递给pattern_match,如果许多调用都固定了my_list,以避免在每次调用中重建u:

u = set()
for pattern in my_list:
    u.update(pattern)

results = [pattern_match(seq, u) for seq in mysequences] 
相关问题