元组部分匹配

2 投票
6 回答
8015 浏览
提问于 2025-04-17 00:16

我有一个包含多个元组的元组,还有一个单独的元组。我想知道第一个元组中的哪些元素和第二个元组匹配(如果有的话),而且我也想考虑部分匹配的情况。

这里有一个过滤函数来演示我的意思。

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

这个过滤器在这种形式下没什么用,因为我不能把模式作为参数从外部传入(我想用同一个函数来检查不同的输入)。有没有办法解决这个问题?

另外,还有什么其他算法可以用来更好地解决原来的问题呢?

6 个回答

2

在编程中,有时候我们会遇到一些问题,特别是在使用某些工具或库的时候。这些问题可能会让我们感到困惑,尤其是当我们刚开始学习编程的时候。比如,有人可能会在使用某个特定的功能时,发现它并没有按照预期的方式工作。这种情况可能是因为我们没有正确理解这个功能的用法,或者是因为我们在代码中犯了一些小错误。

为了帮助大家更好地理解这些问题,很多人会在网上提问,比如在StackOverflow这个网站上。这里有很多经验丰富的程序员,他们会分享自己的经验和解决方案,帮助新手们解决问题。

总之,遇到问题是学习编程的一部分,重要的是要保持耐心,多问问题,积极寻找解决方案。这样才能不断进步,成为更好的程序员。

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

你为什么不使用内置的 filter 呢?

>>> filter(lambda x: x[2] == '1.3', repo)
<<< (('framework', 'django', '1.3'), ('cms', 'fein', '1.3'))

...或者用 列表推导式 呢?

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

如果你想把它封装成一个函数的话:

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

你可以用闭包把模式绑定到函数里:

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

我还提供了一种不同的方式来比较元组。

撰写回答