【问题标题】:Summing similar elements within a tuple-of-tuples对元组中的相似元素求和
【发布时间】:2016-05-23 17:41:59
【问题描述】:

this 问题之后,我现在需要汇总整个元组中的相似条目(元组)。

所以给定一个元组,例如:

T = (('a', 'b', 2),
 ('a', 'c', 4),
 ('b', 'c', 1),
 ('a', 'b', 8),)

对于第一个和第二个元素相同的所有元组,我想对第三个​​元素求和,否则,保留元组。所以我最终会得到以下元组:

(('a', 'b', 10),
 ('a', 'c', 4),
 ('b', 'c', 1),)

封闭元组中元组的顺序(和求和)无关紧要。

我们正在处理元组,所以我们不能利用像 dict.get() 这样的东西。如果我们走defaultdict 路线:

In [1218]: d = defaultdict(lambda: defaultdict(int))

In [1220]: for t in T:
    d[t[0]][t[1]] += t[2]
   ......:     

In [1225]: d
Out[1225]: 
defaultdict(<function __main__.<lambda>>,
            {'a': defaultdict(int, {'b': 10, 'c': 4}),
             'b': defaultdict(int, {'c': 1})})

我不太确定如何将其重构为元组。无论如何,尽管每个元组中三个元素的顺序是一致的,但我对元组的索引并不满意。这可以在不转换为其他数据类型的情况下完成吗?

【问题讨论】:

    标签: python python-2.7 tuples


    【解决方案1】:

    代码 -

    from collections import defaultdict
    
    T1 = (('a', 'b', 2),
     ('a', 'c', 4),
     ('b', 'c', 1),
     ('a', 'b', 8),)
    
    d = defaultdict(int)
    
    for x, y, z in T1:
        d[(x, y)] += z
    
    T2 = tuple([(*k, v) for k, v in d.items()])
    
    print(T2)
    

    输出 -

    (('a', 'c', 4), ('b', 'c', 1), ('a', 'b', 10))
    

    如果你有兴趣保持原来的顺序,那么 -

    from collections import OrderedDict
    
    T1 = (('a', 'b', 2), ('a', 'c', 4), ('b', 'c', 1), ('a', 'b', 8),)
    
    d = OrderedDict()
    
    for x, y, z in T1:
        d[(x, y)] = d[(x, y)] + z if (x, y) in d else z
    
    T2 = tuple((*k, v) for k, v in d.items())
    
    print(T2)
    

    输出 -

    (('a', 'b', 10), ('a', 'c', 4), ('b', 'c', 1))
    

    在 Python 2 中,你应该使用这个 -

    T2 = tuple([(x, y, z) for (x, y), z in d.items()])
    

    【讨论】:

      【解决方案2】:

      你只需要一个defaultdict(int):

      >>> from collections import defaultdict
      >>>
      >>> d = defaultdict(int)
      >>> T = (('a', 'b', 2),
      ...  ('a', 'c', 4),
      ...  ('b', 'c', 1),
      ...  ('a', 'b', 8),) 
      >>>
      >>> for key1, key2, value in T:
      ...     d[(key1, key2)] += value
      ... 
      >>> [(key1, key2, value) for (key1, key2), value in d.items()]
      [
          ('b', 'c', 1), 
          ('a', 'b', 10), 
          ('a', 'c', 4)
      ]
      

      【讨论】:

      • 你可以省略索引中的括号,所以d[key1, key2]而不是d[(key1, key2)]
      • @user2357112 是的,很好,谢谢!但显式总比隐式好。
      • 返回一个列表,但我想我可以tuple() 它。谢谢。
      猜你喜欢
      • 2013-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-07
      • 1970-01-01
      相关资源
      最近更新 更多