【问题标题】:Finding match from a list of tuples从元组列表中查找匹配项
【发布时间】:2020-07-31 07:10:59
【问题描述】:

我有一个如下的元组列表。

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

我想给出像 ('a') 这样的输入,那么它应该给出像这样的输出,

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

或者对于 ('a','b') 的输入,它应该给出

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

我尝试使用但没有成功。

   print(filter(lambda x: ("a","b") in x, x))
>>> <filter object at 0x00000214B3A545F8>

【问题讨论】:

    标签: python list tuples


    【解决方案1】:

    元组在 python 中是按字典顺序匹配的,这意味着元素是成对地比较的,不管它们的类型如何。

    您可以提取每个元组中与您的前缀长度相同的部分,并与==进行比较:

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

    这种类型的列表推导确实等同于filter 调用,所以你可以这样做

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

    进行线性搜索并不是解决此问题的一种非常有效的方法。称为Trie 的数据结构专门用于查找前缀。它将所有数据排列成一棵树。这是一个流行的 Python 实现,您可以使用适当的属性:https://stackoverflow.com/a/11016430/2988730

    【讨论】:

      【解决方案2】:
      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))]
      

      这样:

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

      返回:

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

      【讨论】:

        【解决方案3】:

        首先,使用list(filter(...)) 将过滤器对象转换为列表,但您的过滤器并不能满足您的要求——它检查的是成员资格,而不是子序列。您可以使用切片检查子序列。

        然后你只需要添加一个检查匹配是否比子序列长。

        另外,一个 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)
        

        输出:

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

        【讨论】:

          【解决方案4】:
          list(filter(lambda y: all([y[i] == z for i,z in enumerate(inp)]) if len(y)>=len(inp) else False, x))
          

          对于 inp = ('a', 'b') 输出将是

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

          【讨论】:

            猜你喜欢
            • 2012-12-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-07-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多