【问题标题】:searching through a nested-list in python在python中搜索嵌套列表
【发布时间】:2011-06-20 10:50:54
【问题描述】:

我有一个包含 97510 个值的元组的嵌套列表,如下所示:

a = [ (1,2,3), (3,4,5), (5,4,2)]

每个第一个值 (index=0) 都是唯一的,我需要找到具有相同 index=1 项的其他 index=0 项 在示例中,我需要找到第二个和第三个元组,其中第二个项目 '4' 是常见的。

我该怎么做?

【问题讨论】:

    标签: python list search nested-lists


    【解决方案1】:

    如果要查找所有匹配项:

    >>> from collections import defaultdict
    >>> d = defaultdict(list)
    >>> for inner in a:
    ...     d[inner[1]].append(inner)
    ... 
    >>> d
    defaultdict(<type 'list'>, {2: [(1, 2, 3)], 4: [(3, 4, 5), (5, 4, 2)]})
    >>> d[4]
    [(3, 4, 5), (5, 4, 2)]
    

    如果您想为特定的第二个值挑选出所有匹配项:

    罢工>

    >>> filter(lambda inner: inner[1] == 4, a)
    [(3, 4, 5), (5, 4, 2)]
    

    编辑:正如 cmets 中所指出的,列表推导更可取,因为它对此类工作更有效:

    >>> [inner for inner in a if inner[1] == 4]
    [(3, 4, 5), (5, 4, 2)]
    

    使用timeit 显示列表理解快了大约 2.5 倍(无论如何在我的机器上):

    >>> timeit.timeit('[inner for inner in a if inner[1] == 4]', 'a=[(1,2,3), (3,4,5), (5, 4, 2)]')
    2.5041549205780029
    >>> timeit.timeit('filter(lambda inner: inner[1] == 4, a)', 'a=[(1,2,3), (3,4,5), (5, 4, 2)]')
    6.328679084777832
    

    【讨论】:

    • 我通常更喜欢列表推导而不是 filter 与 lambda - [item for item from a if item[1] == 4]。在我看来,它更适合阅读。
    • @Space_C0wb0y - 是的,我通常也会。不知道为什么我在这个答案中使用过滤器。我已经用一些时间示例对其进行了更新 - 并且更好阅读,更快。
    【解决方案2】:

    这是一种方法:

    >>> result = defaultdict(list)
    >>> for item in a:
    >>>     result[item[1]].append(item)
    >>> result
    defaultdict(<type 'list'>, {2: [(1, 2, 3)], 4: [(3, 4, 5), (5, 4, 2)]})
    

    这将产生一个列表字典,其中具有相同第二个值的所有项目都在一个列表中,该值作为键。

    【讨论】:

      【解决方案3】:

      另一种选择:

      from operator import itemgetter
      from itertools import groupby
      
      a = [ (1,2,3), (3,4,5), (5,4,2)]
      b = groupby(sorted(a), itemgetter(1))
      for val, group in b:
          print val, list(group)
      # 2 [(1, 2, 3)]
      # 4 [(3, 4, 5), (5, 4, 2)]
      

      【讨论】:

      • 不错。我总是忘记 itertools,我需要更多地玩它。
      • 这首先对列表进行排序,然后对其进行迭代。给出 O(n log n) 的复杂度加上对列表的额外遍历。这效率不高。
      【解决方案4】:

      注意你也可以使用groupby:

      from itertools import groupby
      
      data = [ (1,2,3), (3,4,5), (5,4,2)]
      res = groupby(sorted(data), key=lambda x: x[1])
      

      根据评论编辑

      解决了这个问题并找到了另一种解决方案 - 但不是最好的,但是:

      inputVals = [(1,2,3), (3,4,5), (5,4,2), (2,2,3), (7,3,1)]
      for val in set(x[1] for x in inputVals):   
          print val, list(set(sval for sval in inputVals if sval[1] == val))
      

      【讨论】:

      • 当然,谢谢,我的回答只是为了通知 OP 他还有一个选择。
      猜你喜欢
      • 2013-11-26
      • 1970-01-01
      • 1970-01-01
      • 2010-12-12
      • 1970-01-01
      • 2014-03-06
      • 2018-10-15
      • 1970-01-01
      • 2011-10-16
      相关资源
      最近更新 更多