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

在这种情况下,如何使用python中的过滤器过滤字典?,python,dictionary,filter,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。 我试过: d2 = dict(filter(lambda a,

我以前从未使用过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。 我试过:

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

您的
defaultdict
中不会有一个集群
1
,但是如果您知道您期望的集群是什么,那么整个世界都会很好(因为当您尝试查看时,空列表将放在该插槽中--这是
defaultdict
的“默认”部分):


FWIW,用内置的
过滤器解决这个问题简直是疯了。但是,如果您必须这样做,以下类似的方法也会起作用:

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
不仅仅是一个创建隐式循环的工具,因此实际上返回我们想要的dict):

但这仍然是非常丑陋的python

>>> 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]}
  • lambda函数来获取值列表
  • map函数使用上述lambda映射值(簇)

  • 我们不能在这个问题上使用循环。啊,我明白了。我错过了。好吧,这是可能的(我刚刚在终端上做过)——但这种限制让这更像是一个家庭作业问题(设计得很糟糕),我不想直接给你答案。这样做时,
    filter
    实际上只是一个在项目上循环的工具。你做了什么尝试?如果我们能看到这一点以及你的困境,那么也许我们可以看看并帮助你找到一个可接受的解决方案。但是我很困惑如何在带过滤器的字典中比较不同对中的对[1]。我刚刚发布了我的试用案例。但由于我以前从未使用过python,它有一些语法错误。如何在字典中比较每对中的[1]对?@LiyuanLiu--我添加了一些选项,但没有一个是好的。
    d2 = {}
    filter(lambda pt: d2.setdefault(d1[pt], []).append(pt), d1)
    
    >>> 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]}
    
    >>> 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]}