【问题标题】:How to create a new list of tuples based on a values from original list of tuples?如何根据原始元组列表中的值创建新的元组列表?
【发布时间】:2015-08-06 16:52:33
【问题描述】:

我的函数正在返回:

[('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]

但是,我需要最终输出为:

[('a', 'h'), ('d', 'g')]

如您所见,如果 i[1] 和 i[2] 匹配,我需要将 i[0] 配对在一起。

我正在尝试使用 for 循环,但目前我想不出如何编写它。

【问题讨论】:

标签: python python-3.x tuples


【解决方案1】:

这似乎有效:

from itertools import combinations

l = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
print([(a[0], b[0]) for a, b in combinations(l, 2) if a[1:] == b[1:]])

【讨论】:

    【解决方案2】:

    您可以通过根据第二个和第三个元素对列表进行排序,然后使用itertools.groupby 来做到这一点。然后对于每个组,您可以从其中的元素中获取第一个元素。示例 -

    >>> a = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
    >>> lst = []
    >>> new_a = sorted(a, key=lambda i: (i[1], i[2]))
    >>> for _, x in itertools.groupby(new_a, lambda i: (i[1], i[2])):
    ...     lst.append(tuple(y[0] for y in x))
    ...
    >>> lst
    [('a', 'h'), ('d', 'g')]
    

    这也可以在一行中完成(虽然不可读) -

    >>> l = [tuple(y[0] for y in x) for _, x in itertools.groupby(sorted(a, key=lambda i: (i[1], i[2])), lambda i: (i[1], i[2]))]
    >>> l
    [('a', 'h'), ('d', 'g')]
    

    【讨论】:

    • 不必要的n log n排序
    • 当您可以使用 dict 进行分组时,这是不必要的
    【解决方案3】:

    根据每个元组的第二个和第三个元素进行分组,将第一个元素附加到列表中,然后过滤掉长度

    from collections import defaultdict
    
    d = defaultdict(list)
    for a,b,c in l:
        d[b,c].append(a)
    
    print([tuple(val) for val in d.values() if len(val)>1])
    [('a', 'h'), ('d', 'g')]
    

    要保证第一个匹配顺序,请使用 OrderedDict:

    from collections import OrderedDict
    d = OrderedDict()
    for a,b,c in l:
        d.setdefault((b,c),[]).append(a)
    
    print([tuple(val) for val in d.values() if len(val)>1])
    

    【讨论】:

      【解决方案4】:

      我认为此解决方案将保留顺序(基于初始匹配位置):

      from itertools import groupby
      from operator import itemgetter
      from collections import defaultdict
      
      x = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
      groupings, seen_list=defaultdict(list), []
      
      for key, value in groupby(x, itemgetter(1, 2)):
          if key not in seen_list:
               seen_list.append(key)
          groupings[key].extend(list(map(itemgetter(0),value)))
      
      print([groupings[key] for key in seen_list])
      

      如果顺序不重要,您可以忽略 seen_list,只打印 groupings.values()

      x = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]
      groupings=defaultdict(list)
      for key, value in groupby(x, itemgetter(1, 2)):
          groupings[key].extend(list(map(itemgetter(0),value)))
      
      print(groupings.values())
      

      【讨论】:

      • 你可以这样做print groupings.values()
      • 确定顺序不重要(未指定:P)
      • 然后你可以用seen_list分两部分给出答案,另一部分没有它,顺便说一句,好的答案是赞成的人:)
      • 顺序无关紧要 - 只要匹配对在一起
      【解决方案5】:

      可能不是那么 Pythonic,但更容易一些:

      >>> a = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'e', 'f'), ('h', 'b', 'c')]    
      >>> c = {}
      >>> [c[j+k].append(i) if j+k in c else c.update({j+k:[i]}) for i,j,k in a]
      >>> c = c.values()
      >>> print c
      [['d', 'g'], ['a', 'h']]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-16
        • 2021-10-28
        • 1970-01-01
        • 2019-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多