如何在python中使用过滤器来过滤这种情况下的字典?

时间:2016-04-06 04:25:14

标签: python dictionary filter

我之前从未使用过python。现在我有一个字典:

d1 = {1:2,3:3,2:2,4:2,5:2}

每对中的对[0]表示点,每对中的对[1]表示簇ID。因此d1表示点1属于集群2,点3属于集群3,点2属于集群2,点4属于集群2,点5属于集群2.没有点属于集群1。 如何使用过滤器(不要使用循环)来获取如下字典:

d2 = {1:[],2:[1,2,4,5],3:[3]}

表示没有点属于集群1,1,2,4,5属于集群2,3,3属于集群3。 我试过了:

d2 = dict(filter(lambda a,b: a,b if a[1] == b[1] , d1.items()))

2 个答案:

答案 0 :(得分:1)

我会使用collections.defaultdict

from collections import defaultdict

d2 = defaultdict(list)
for point, cluster in d1.items():
    d2[cluster].append(point)

您的defaultdict在其中没有群集1,但如果您知道您期望的群集,那么全世界都可以(因为空列表会被放置)当你试图看那里时,在那个插槽中 - 这是defaultdict的"默认"部分:

expected_clusters = [1, 2, 3]
for cluster in expected_clusters:
    print(d2[cluster])

FWIW,使用内置filter来解决这个问题只是精神错乱。但是,如果必须,可以使用以下内容:

d2 = {}
filter(lambda (pt, cl): d2.setdefault(cl, []).append(pt), d1.items())

请注意,我使用python2.x解压缩参数。对于python3.x,你需要做类似lambda item: d2.setdefault(item[1], []).append(item[0])的事情,或者,也许我们可以做一些更好的事情:

d2 = {}
filter(lambda pt: d2.setdefault(d1[pt], []).append(pt), d1)

我们可以使用reduce内置更好地做微小的(至少reduce并不是创建隐式循环的工具,因此实际上返回我们想要的字典:

>>> d1 = {1:2,3:3,2:2,4:2,5:2}
>>> reduce(lambda d, k: d.setdefault(d1[k], []).append(k) or d, d1, {})
{2: [1, 2, 4, 5], 3: [3]}

但这仍然是真的丑陋的python。

答案 1 :(得分:0)

>>> d1 = {1:2,3:3,2:2,4:2,5:2}
>>> dict(map(lambda c : (c, [k for k, v in d1.items() if v == c]), d1.values()))
{2: [1, 2, 4, 5], 3: [3]}
  1. lambda函数获取值列表
  2. 使用上述lambda
  3. 映射函数以映射值(簇)