Pythonic的写作方式属于两套功能

时间:2015-07-10 10:50:00

标签: python set

我有两组只包含字符串,我正在尝试编写一个函数:

def belongs(setA, setB):
   return True/False

定义:如果setsetB有一个项目包含string包含setA中的项目,那么我致电setB 属于setA。一些例子:

setA = set(['apple', 'banana', 'strawberry'])

set1 = set(['abcc', 'xyz', 'klm'])                   # does not belong to setA
set2 = set(['app', 'banaba', 'baba'])                # does not belong to setA
set3 = set(['apples', 'xyz'])                        # belongs to setA
set4 = set(['bananaaa', 'hello', 'world', 'stack'])  # belongs to setA

我目前的代码:

def belongs(set1, set2):
    for i in set1:
        for j in set2:
            if i in j:
                return True
    return False

是否有更好/更多的Pythonic方式做同样的事情?

2 个答案:

答案 0 :(得分:4)

编写函数:

def belongs(set1, set2):
    return any(s1 in s2 for s1 in set1 for s2 in set2)

测试一下:

assert not belongs(setA, set1)
assert not belongs(setA, set2)
assert belongs(setA, set3)
assert belongs(setA, set4)

答案 1 :(得分:2)

检查来自setA的任何字符串是setB中任何项目的子字符串的问题,即setB"是否属于"可以使用setA来解决grep -F

grep -Flf setA set1 set2 set3 set4打印"属于"的集合。在这种情况下,setAset3set4Aho–Corasick string matching algorithm构成了原始Unix命令fgrep的基础。对于大输入而言,它比具有嵌套循环的天真解决方案(例如from 20 hours for a brute-force approach down to a couple of minutes using fgrep)更有效。

如果您无法安装第三方库;您可以尝试使用re模块,以便在需要时提高性能:

import re
from itertools import imap

substrings = sorted(setA, key=len, reverse=True) # longest first
found = re.compile("|".join(map(re.escape, substrings))).search
print([any(imap(found, S)) for S in [set1, set2, set3, set4]])
# -> [False, False, True, True]