【问题标题】:Filter operation in PythonPython中的过滤操作
【发布时间】:2013-08-16 20:11:39
【问题描述】:

我正在寻找一种无需太多样板代码的 Python 方法。

假设我有一个列表:

[(a,4),(b,4),(a,5),(b,3)]

我正在尝试找到一个允许我按第一个元组值排序的函数,并将列表值合并在一起,如下所示:

[(a,[4,3]),(b,[4,5])]

我知道我可以用幼稚的方式做到这一点,但我想知道是否有更好的方法。

【问题讨论】:

  • 输出中的 5 是如何变成 3 的?

标签: python python-2.7 map reduce


【解决方案1】:

使用collections.defaultdict(list):

from collections import defaultdict

lst = [("a",4), ("b",4), ("a",5), ("b",3)]

result = defaultdict(list)
for a, b in lst:
    result[a].append(b)

print sorted(result.items())

# prints: [('a', [4, 5]), ('b', [4, 3])]

在排序之前,算法具有O(n) 复杂度; group by 算法有 O(n * log(n)) 并且 set/list/dict 理解有一些大于 O(n^2)

【讨论】:

  • i[0]i[1]?为什么不直接解包元组?
  • 不,不是。 for key, value in lst:
  • 啊,真正的原因是凌晨1点22分
【解决方案2】:

假设 'a' 是您的初始列表,而 'b' 是预期结果,则以下代码将起作用:

d = {}
for k, v in a:
    if k in d:
        d[k].append(v)
    else:
        d[k] = [v] 
b = d.items()

【讨论】:

  • 这是我写的幼稚解决方案
  • 这是另一个选项 [(key,[v2 for k2, v2 in a if k2 == key ]) for key in list(set(map(lambda x: x[0], a) ))]
【解决方案3】:

效率不高,但足够了(使用 set + list + dict 理解):

>>> data = [("a",4), ("b",4), ("a",5), ("b",3)]
>>> {key: [v for k, v in data if k == key]
...  for key in {k for k, v in data}
... }.items()
[('a', [4, 5]), ('b', [4, 3])]

【讨论】:

  • 我确信这很好,但读起来却是一场噩梦,我希望任何 Python 水平的人都能读到它。
  • 这不是很好,但它是一种不使用任何语句的方法:D
  • 确实效率不高但是我还是觉得这个是最容易理解的。
【解决方案4】:

另一个选项(再次假设 'a' 是初始列表)

[(key,[v2 for k2, v2 in a if k2 == key ]) for key in list(set(map(lambda x: x[0], a)))]

【讨论】:

  • 不需要转换为list,因为该集合已经是可迭代的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多