【问题标题】:Any pythonic way to do "[['a', 2], ['b',1]] + [['b', 2], ['c', 1]] = [['b', 3], ['a', 2], ['c', 1]]"?任何pythonic方式来做“[['a', 2], ['b',1]] + [['b', 2], ['c', 1]] = [['b', 3] , ['a', 2], ['c', 1]]"?
【发布时间】:2013-11-22 07:04:05
【问题描述】:

输入:

[['a', 2], ['b',1]] (sorted by value)
[['b', 2], ['c', 1]]

输出:

[['b', 3], ['a', 2], ['c', 1]]

任何pythonic方式?当然,在 Python 中! (更适合 2.6 倍) 谢谢!

【问题讨论】:

  • 你确定不想要字典吗?
  • 你想单独使用列表吗?
  • 因为,输出将编码为 JSON。而且,大多数时候,系统只需要最上面的那个。无论如何,这是一个有趣的问题,不是吗?

标签: python lambda functional-programming


【解决方案1】:

对 Python2.7+ 使用 collections.Counter

>>> from collections import Counter
>>> lis1 = [['a', 2], ['b',1]]
>>> lis2 = [['b', 2], ['c', 1]]
>>> c = Counter(dict(lis1)) + Counter(dict(lis2))
>>> c.most_common()
[('b', 3), ('a', 2), ('c', 1)]

如果列表包含重复项,则需要将Counter 示例修改为:

>>> lis1 = [['a', 2], ['b',1], ['b',5]]
>>> lis2 = [['b', 2], ['c', 1], ['a', 10]]
>>> from itertools import chain
>>> from collections import Counter
>>> c = sum((Counter(dict([x])) for x in chain(lis1, lis2)), Counter())
>>> c.most_common()
[('a', 12), ('b', 8), ('c', 1)]

对于 2.5 collections.defaultdict:

>>> from collections import defaultdict
>>> d = defaultdict(int)
>>> for k, v in lis1 + lis2:
    d[k] += v
...     
>>> sorted(d.items(), key=lambda x:x[1], reverse=True)
[('b', 3), ('a', 2), ('c', 1)]

【讨论】:

  • 最后添加:map((lambda x: [x[0], x[1]]), t)?
  • @Kane: map(list, whatever_you_called_the_output) 如果你想要列表而不是元组。
【解决方案2】:

由于python 2.6 的集合中没有Counter 类,所以这个就可以了。可以使用defautldict,但它的使用并不能简化代码:

a = [['a', 2], ['b', 1]]
b = [['b', 2], ['c', 1]]
rv = {}
for k, v in a + b:
    rv[k] = rv.setdefault(k, 0) + v

预期结果的输出,转换为列表列表:

>>> map(list, sorted(rv.items(), key = lambda x: x[1], reverse=True))
[['b', 3], ['a', 2], ['c', 1]]

【讨论】:

    【解决方案3】:

    只是把这个答案扔在这里,但是,您可能希望将它们组合成一个列表,然后计算它们:

    >>> a = [['a', 2], ['b',1]]
    >>> b = [['b', 2], ['c', 1]]
    >>> a + b
    [['a', 2], ['b', 1], ['b', 2], ['c', 1]]
    >>> "".join(c*n for c, n in a+b)
    'aabbbc'
    >>> from collections import Counter
    >>> Counter("".join(c*n for c, n in a+b))
    Counter({'b': 3, 'a': 2, 'c': 1})
    >>> Counter("".join(c*n for c, n in a+b)).most_common()
    [('b', 3), ('a', 2), ('c', 1)]
    

    【讨论】:

      【解决方案4】:

      您可以简单地从您的元组列表(在您的情况下为列表)创建字典,然后添加它们的计数器。

      >>> from collections import Counter
      >>> a = [['b', 2], ['c', 1]]
      >>> b = [['a', 2], ['b',1]]
      >>> sorted(dict(Counter(dict(a)) + Counter(dict(b))).items(),key= lambda x:-x[1])
      [('b', 3), ('a', 2), ('c', 1)]
      

      【讨论】:

        【解决方案5】:

        不错

        从集合导入计数器

        lis1 = [['a', 2], ['b',1]]

        lis2 = [['b', 2], ['c', 1]]

        c = 计数器(dict(lis1)) + 计数器(dict(lis2))

        c.most_common()

        [('b', 3), ('a', 2), ('c', 1)]
        

        python 2.5 和 2.6 中的collections.defaultdict 和 2.7 及更高版本中的 collections.Counter

        从集合导入默认字典

        d = defaultdict(int)

        对于 lis1 + lis2 中的 k、v:

        d[k] += v
        

        排序(d.items(), key=lambda x:x[1], reverse=True)

         [('b', 3), ('a', 2), ('c', 1)]
        

        【讨论】:

          【解决方案6】:

          答案:

          >>> 从集合导入计数器 >>> p = [['a', 2], ['b',1]] >>> q = [['b', 2], ['c', 1]] >>> m = 计数器(dict(p))+ 计数器(dict(q)) >>> 排序(m.items(), key=lambda x:x[1], reverse=True) [('b', 3), ('a', 2), ('c', 1)]

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-06-13
            • 1970-01-01
            • 2021-01-30
            • 2016-10-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多