Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 元组部分匹配_Python_Algorithm_Tuples_Matching - Fatal编程技术网

Python 元组部分匹配

Python 元组部分匹配,python,algorithm,tuples,matching,Python,Algorithm,Tuples,Matching,我有一个元组和一个元组。我想知道第一个元组的哪些元素与第二个元组(如果有的话)匹配,同时考虑部分匹配 这是一个过滤器函数来演示我的意思 def f(repo): pattern = (None, None, '1.3') for idx, item in enumerate(pattern): if item != None and item != repo[idx]: return False return True >&

我有一个元组和一个元组。我想知道第一个元组的哪些元素与第二个元组(如果有的话)匹配,同时考虑部分匹配

这是一个过滤器函数来演示我的意思

def f(repo):
    pattern = (None, None, '1.3')
    for idx, item in enumerate(pattern):
        if item != None and item != repo[idx]:
            return False
    return True

>>> repo = (('framework', 'django', '1.3'), ('cms', 'fein', '1.3'), ('cms', 'django-cms', '2.2'))
>>> filter(f, repo)
(('framework', 'django', '1.3'), ('cms', 'fein', '1.3'))
过滤器在这种形式下是无用的,因为模式不能作为参数在外部提供(我想使用相同的函数检查不同的输入)。有办法解决这个问题吗


另外,为了更好地解决原始问题,还有什么算法可以采用呢?

为什么不使用内置的:

>>过滤器(lambda x:x[2]='1.3',回购)
>[x代表回购协议中的x,如果x[2]=“1.3”]
>repo_过滤器('version','1.3')
那么:

def f(repo, pattern=None):
    if not pattern:
        pattern = (None, None, '1.3')
    for idx, item in enumerate(pattern):
        if item and item != repo[idx]:
            return False
    return True

repo = (('framework', 'django', '1.3'), ('cms', 'fein', '1.3'), ('cms', 'django-cms', '2.2'))

[x for x in repo if f(x)]
>>>[('framework', 'django', '1.3'), ('cms', 'fein', '1.3')]    

[x for x in repo if f(x, ('cms',None, None))]
>>> [('cms', 'fein', '1.3'), ('cms', 'django-cms', '2.2')]

可以使用闭包将模式绑定到函数中:

types = {'desc': 0, 'name': 1, 'version': 2}
def repo_filter(type, critera, repo=repo, types=types):
    return [x for x in repo if x[types[type]] == critera]

>>> repo_filter('version', '1.3')
<<< [('framework', 'django', '1.3'), ('cms', 'fein', '1.3')]
def matcher(pattern):
    def f(repo):
        return all(p is None or r == p for r, p in zip(repo, pattern))
    return f

>>> repo = (('framework', 'django', '1.3'), ('cms', 'fein', '1.3'), ('cms', 'django-cms', '2.2'))
>>> pattern = (None, None, '1.3')
>>> filter(matcher(pattern), repo)
(('framework', 'django', '1.3'), ('cms', 'fein', '1.3'))

我还提供了一个用于比较元组的不同表达式。

您可以使用以下表达式:

repo = (('framework', 'django', '1.3'), ('cms', 'fein', '1.3'), ('cms', 'django-cms', '2.2'))
p = (None, None, '1.3')
matches = [i for i in repo if i[0]==p[0] or i[1]==p[1] or i[2]==p[2]]
或使用闭包,例如:

def matcher(pattern):
    def pattern_matcher(repo):
        for idx, item in enumerate(pattern):
            if item is not None and item != repo[idx]:
                return False
        return True
    return pattern_matcher
然后可以这样调用:

filter(matcher(pattern), repo)

检查
None
@TylerCrompton时始终使用
is
运算符:谢谢,你显然是对的。但这并不是代码的唯一问题。我已经更改了
!=None
进入
不是None
并修复了过早返回
True
的问题。现在应该更好了。我只是浏览了一下代码,注意到了一个小细节。我评论了每个人的观点,以便将来的读者都知道正确的方法。:)检查
None
时始终使用
is
运算符。检查
None
时始终使用
is
运算符。
repo = (('framework', 'django', '1.3'), ('cms', 'fein', '1.3'), ('cms', 'django-cms', '2.2'))
p = (None, None, '1.3')
matches = [i for i in repo if i[0]==p[0] or i[1]==p[1] or i[2]==p[2]]
def matcher(pattern):
    def pattern_matcher(repo):
        for idx, item in enumerate(pattern):
            if item is not None and item != repo[idx]:
                return False
        return True
    return pattern_matcher
filter(matcher(pattern), repo)
In [43]: [r for r in repo if all((p is None or q==p) for q,p in zip(r,pattern))]
Out[43]: [('framework', 'django', '1.3'), ('cms', 'fein', '1.3')]