代码之家  ›  专栏  ›  技术社区  ›  Ejaz

如何用元组中的一个项筛选元组列表?

  •  2
  • Ejaz  · 技术社区  · 6 年前

    d = [('A', 'B', 1), ('C', 'D', 1), 
         ('B', 'D', 2), ('A', 'B', 3), 
         ('A', 'D', 3), ('B', 'C', 4), 
         ('A', 'C', 5), ('B', 'C', 8)]
    

    在这里,元组中的前两项是节点,第三项是权重。我想删除具有相同第一和第二节点(两个元组之间的相同第一和第二节点)但权重更高的元组。

    d = [('A', 'B', 1), ('C', 'D', 1), 
         ('B', 'D', 2), ('A', 'D', 3), 
         ('B', 'C', 4), ('A', 'C', 5)]
    

    我试过类似的方法,但看起来不是很干净。

    edge_dict = {}
    
    for x in d:
        key = '%s%s' % (x[0], x[1])
        if not edge_dict.get(key):
            edge_dict[key] = x[2]
        else:
            if edge_dict[key] > x[2]:
                edge_dict[key] = x[2]       
    
    final_list = []
    for k, v in edge_dict.items():
        t = list(k)
        t.append(v)
        final_list.append(tuple(t))
    
    
    final_list.sort(key=lambda x: x[2])
    print final_list    
    
    4 回复  |  直到 6 年前
        1
  •  2
  •   niraj    6 年前

    sorted_res = sorted(d, key = lambda x:((x[0], x[1]), x[2]),reverse=True)
    print(sorted_res)
    

    [('C', 'D', 1),
     ('B', 'D', 2),
     ('B', 'C', 8),
     ('B', 'C', 4),
     ('A', 'D', 3),
     ('A', 'C', 5),
     ('A', 'B', 3),
     ('A', 'B', 1)]
    

    dictionary 前两个元素的键和值将是最新的小元素:

    my_dict = {(i[0], i[1]):i for i in sorted_res}
    print(my_dict)
    

    {('A', 'B'): ('A', 'B', 1),
     ('A', 'C'): ('A', 'C', 5),
     ('A', 'D'): ('A', 'D', 3),
     ('B', 'C'): ('B', 'C', 4),
     ('B', 'D'): ('B', 'D', 2),
     ('C', 'D'): ('C', 'D', 1)}
    

    list(my_dict.values())
    

    结果:

    [('A', 'C', 5),
     ('A', 'B', 1),
     ('A', 'D', 3),
     ('B', 'D', 2),
     ('C', 'D', 1),
     ('B', 'C', 4)]
    

    sorted dictionary comprehension

    result = list({(i[0], i[1]):i 
                 for i in sorted(d, key = lambda x:((x[0], x[1]), x[2]),reverse=True)}.values())
    
        2
  •  2
  •   wwii    6 年前

    只是一点重构。

    edge_dict = {}
    
    for t in d:
        key = t[:2]
        value = t[-1]
        if key in edge_dict:
            edge_dict[key] = min(value, edge_dict[key]) 
        else:
            edge_dict[key] = value
    
    final_list = [(q,r,t) for (q,r),t in edge_dict.items()]
    final_list.sort(key=lambda x: x[2])
    
        3
  •  1
  •   Ajax1234    6 年前

    itertools.groupby ,并在每个分组中选择最小值:

    import itertools
    d = [('A', 'B', 1), ('C', 'D', 1), 
     ('B', 'D', 2), ('A', 'B', 3), 
     ('A', 'D', 3), ('B', 'C', 4), 
     ('A', 'C', 5), ('B', 'C', 8)]
    new_d = [min(list(b), key=lambda x:x[-1]) for _, b in itertools.groupby(sorted(d, key=lambda x:x[:-1]), key=lambda x:x[:-1])]
    

    [('A', 'B', 1), ('A', 'C', 5), ('A', 'D', 3), ('B', 'C', 4), ('B', 'D', 2), ('C', 'D', 1)]
    
        4
  •  1
  •   Taohidul Islam    6 年前

    1. 使用节点对的排序形式作为字典 key

    check_dict={} #This will store the minimum valued nodes
    
    for i in d:
        if check_dict.get((i[0],i[1])) ==None: #if the node is absent then add it to the check_dict
            check_dict[tuple(sorted((i[0],i[1])))] = i[2]
        else: #if the node is present then compare with the previous value and store the minimum one
            check_dict[tuple(sorted((i[0],i[1])))] = min(check_dict[(i[0],i[1])],i[2]) #used sorted to treat ('A','B') as same as ('B',A')
    expected_list = [tuple(key+(value,)) for key,value in check_dict.items()] #create your list of tuples
    print(expected_list)
    

    [('A', 'B', 1), ('C', 'D', 1), ('B', 'D', 2), ('A', 'D', 3), ('B', 'C', 4), ('A', 'C', 5)]