如何通过pythonical生成给定对象列表的成员字典?

如何通过pythonical生成给定对象列表的成员字典?,python,dictionary,set,Python,Dictionary,Set,我有一个此类对象的列表: class foo: def __init__(self,x,y): self.x = x self.y = y def __repr__(self): return "(" + str(self.x) + "," + str(self.y) + ")" 现在我想创建一个字典,为x的每个值包含y值的列表(排序的、唯一的元素)。这是我写的 def get_xy_dict(lis): outp = {

我有一个此类对象的列表:

class foo:
    def __init__(self,x,y):
        self.x = x
        self.y = y
    def __repr__(self):
        return "(" + str(self.x) + "," + str(self.y) + ")"
现在我想创建一个字典,为
x
的每个值包含
y
值的列表(排序的、唯一的元素)。这是我写的

def get_xy_dict(lis):
    outp = {}
    for e in lis:
        if (e.x in outp): 
            outp[e.x].add(e.y)
        else:
            outp[e.x] = set([e.y])
    return outp
像这样使用它,它可以按预期工作:

x = [ foo(1,2), foo(1,3), foo(3,6), foo(1,3)]
y = get_xy_dict(x)
print(x)
print(y)
印刷品(见):

然而,我觉得我的代码非常笨拙。此外,我更喜欢列表而不是集合。也许可以完全避免使用这些集合。而且,输出被排序只是偶然的,如果我加上这一点,它将变得更加笨拙

获得相同输出的python方法是什么(最好是列表而不是集合)?例如,如何生成包含给定
x
出现的所有
y
值的字典?


PS:不确定,如果这属于codereview,请告诉我。

您可以使用该函数轻松地将集合更改为排序列表。结合a,您可以大大简化代码:

from collections import defaultdict

def get_xy_dict(lis):
    d = defaultdict(set)
    for e in lis:
        d[e.x].add(e.y)
    return {k: sorted(v) for k, v in d.items()}  # This creates a new dict, but you could also 
                                                 # change the values of d

x = [ foo(1,2), foo(1,3), foo(3,6), foo(1,3)]
y = get_xy_dict(x)
print(x)  # [(1,2), (1,3), (3,6), (1,3)]
print(y)  # {1: [2, 3], 3: [6]}

您可以使用该函数轻松地将集合更改为排序列表。结合a,您可以大大简化代码:

from collections import defaultdict

def get_xy_dict(lis):
    d = defaultdict(set)
    for e in lis:
        d[e.x].add(e.y)
    return {k: sorted(v) for k, v in d.items()}  # This creates a new dict, but you could also 
                                                 # change the values of d

x = [ foo(1,2), foo(1,3), foo(3,6), foo(1,3)]
y = get_xy_dict(x)
print(x)  # [(1,2), (1,3), (3,6), (1,3)]
print(y)  # {1: [2, 3], 3: [6]}

首先需要按x属性对foo项进行排序,然后才能对它们进行分组

一种方法是使用
itertools.groupby
,如下所示:

导入itertools
进口经营者
sort\u key=operator.attrgetter('x')
y={k:set(v.y表示组中的v)
对于k,在itertools.groupby中分组(排序(x,key=sort\u key),sort\u key)}
打印(y)
你会得到:

{1:{2,3},3:{6}

首先需要按x属性对foo项进行排序,然后才能对它们进行分组

一种方法是使用
itertools.groupby
,如下所示:

导入itertools
进口经营者
sort\u key=operator.attrgetter('x')
y={k:set(v.y表示组中的v)
对于k,在itertools.groupby中分组(排序(x,key=sort\u key),sort\u key)}
打印(y)
你会得到:

{1:{2,3},3:{6}

您可以使用collections.defaultdict或方法setdefault fromdictionaries@DanielMesejo你能详细说明一下吗?这段代码已经到了我对python的了解的极限,我只想知道当你说sorted时,你指的是按出现的顺序排序?
outp=defaultdict(set)
;然后
outp[e.x].add(e.y)
按照您想要的方式工作,无论您是否实际看过
e.x
。@DanielMesejo no实际上
y
值的列表应该被排序。在编写问题后,我才意识到在我的代码中不是这样(在输出中它被排序,但只是偶然),您可以使用collections.defaultdict或方法setdefault fromdictionaries@DanielMesejo你能详细说明一下吗?这段代码已经到了我对python的了解的极限,我只想知道当你说sorted时,你指的是按出现的顺序排序?
outp=defaultdict(set)
;然后
outp[e.x].add(e.y)
按照您想要的方式工作,无论您是否实际看过
e.x
。@DanielMesejo no实际上
y
值的列表应该被排序。在写了问题后才意识到我的代码中不是这样(在输出中它是排序的,但只是偶然的)