简体   繁体   English

从元组列表中查找匹配项

[英]Finding match from a list of tuples

I have a list of tuples as below.我有一个如下的元组列表。

x = [('b', 'c'),
 ('c',),
 ('a', 'c', 'b'),
 ('b', 'c', 'a', 'd'),
 ('b', 'c', 'a'),
 ('a', 'b'),
 ('a', 'b', 'c', 'd'),
 ('a', 'c', 'b', 'd'),
 ('b',),
 ('c', 'a'),
 ('a', 'b', 'c'),
 ('a',)]

I want to give input like ('a') then it should give output like,我想提供像 ('a') 这样的输入,那么它应该像 output 一样,

[('a', 'c', 'b'), ('a', 'b'),('a', 'b', 'c', 'd'),('a', 'c', 'b', 'd'),('a', 'b', 'c')]
#everything starts with a. But not "a".

or for input of ('a','b') it should give an output of或者对于 ('a','b') 的输入,它应该给出一个 output

[('a', 'b', 'c', 'd'),('a', 'b', 'c')]
#everything start with ('a','b') but not ('a','b') itself.

I tried to use but no success.我尝试使用但没有成功。

   print(filter(lambda x: ("a","b") in x, x))
>>> <filter object at 0x00000214B3A545F8>
def f(lst, target):
    return [t for t in lst if len(t) > len(target) and all(a == b for a, b in zip(t, target))]

so that:以便:

f(x, ('a', 'b'))

returns:返回:

[('a', 'b', 'c', 'd'), ('a', 'b', 'c')]

Tuples are matched lexicographically in python, meaning that there elements are compared pair by pair, regardless of their type.元组在 python 中按字典顺序匹配,这意味着无论它们的类型如何,都会成对地比较元素。

You can extract the portion of each tuple of the same length as your prefix and compare with == :您可以提取与前缀长度相同的每个元组的部分,并与==进行比较:

def find_prefixes(prefix, sequence):
    n = len(prefix)
    return[x for x in sequence if x[:n] == prefix and len(x) > n]

List comprehensions of this type are indeed equivalent to filter calls, so you can do这种类型的列表推导确实相当于filter调用,所以你可以这样做

def find_prefixes(prefix, sequence):
    n = len(prefix)
    return list(filter(lambda x: x[:n] == prefix and len(x) > n, sequence))

Doing a linear search is not a very efficient way to solve this problem.进行线性搜索并不是解决此问题的一种非常有效的方法。 The data structure known as a Trie is made specifically for finding prefixes.称为Trie的数据结构专门用于查找前缀。 It arranges all your data into a single tree.它将所有数据排列成一棵树。 Here is a popular Python implementation you can use with the appropriate attribution: https://stackoverflow.com/a/11016430/2988730这是一个流行的 Python 实现,您可以使用适当的属性: https://stackoverflow.com/a/11016430/2988730

Firstly, use list(filter(...)) to convert a filter object to a list, but your filter doesn't do what you want - it checks membership, not subsequence.首先,使用list(filter(...))将过滤器 object 转换为列表,但您的过滤器不会做您想做的事情 - 它检查成员资格,而不是子序列。 You can check subsequence by using a slice.您可以使用切片检查子序列。

Then you just need to add a check that the match is longer than the subsequence.然后你只需要添加一个检查,即匹配比子序列长。

Also, a filter of a lambda is better written as a comprehension.此外,最好将 lambda 的过滤器写成理解。

for sub in ('a',), ('a', 'b'):
    n = len(sub)
    out = [t for t in x if t[:n] == sub and len(t) > n]
    print(out)

Output: Output:

[('a', 'c', 'b'), ('a', 'b'), ('a', 'b', 'c', 'd'), ('a', 'c', 'b', 'd'), ('a', 'b', 'c')]
[('a', 'b', 'c', 'd'), ('a', 'b', 'c')]
list(filter(lambda y: all([y[i] == z for i,z in enumerate(inp)]) if len(y)>=len(inp) else False, x))

for inp = ('a', 'b') output will be对于 inp = ('a', 'b') output 将是

[('a', 'b'), ('a', 'b', 'c', 'd'), ('a', 'b', 'c')]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM