【问题标题】:Python get objects in list with matching attributesPython获取列表中具有匹配属性的对象
【发布时间】:2013-12-13 00:58:08
【问题描述】:

我有一个对象列表,需要获取一个属性具有相同值的所有对象以进一步处理它们。我在谷歌上搜索到的所有内容都已经知道我正在寻找的价值。相反,我只需要火柴。说我有这个

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

p1 = Person("mike", 28)
p2 = Person("joe", 28)
p3 = Person("nick", 27)
p4 = Person("Janet", 27)
people = [p1, p2, p3]
#need something like
matches = getMatches(people, "age")
print matches
[[Mike's object, Joe' Object], [Nick's object, Janet's object]]

我想出了这个并且它有效,但对我来说似乎有点蹩脚

def getMatches(objs, attr):
    def Gen(objs, attr):
        used = [] #already searched for these...
        for obj in objs:
            a = getattr(obj, attr)
            if a not in used:
                yield [p for p in objs if getattr(p, attr) == a]
            used.append(a)
    gen = Gen(objs, attr)
    return [g for g in gen]

在我的实际代码中,需要这个更有意义。任何人都可以帮我清理这个问题吗?或者是否有标准的功能或方法来完成这个我只是不知道?

我很欣赏这些答案,最终使用 groupby 并确保首先对其进行排序。这是我第一次尝试编写生成器。如果我可能会问,可以这么说,是什么让我的代码正确和 Pythonic?

【问题讨论】:

    标签: python list attributes generator


    【解决方案1】:

    你可以像这样使用operator.attrgetteritertools.groupby

    from operator import attrgetter
    from itertools import groupby
    def getMatches(people, prop):
        people = sorted(people, key = attrgetter(prop))
        return [list(grp) for k, grp in groupby(people, attrgetter(prop))]
    
    print getMatches(people, "age")
    

    你可以这样检查结果

    for group in getMatches(people, "age"):
        print [people.name for people in group]
    

    输出

    ['mike', 'joe']
    ['nick', 'Janet']
    

    【讨论】:

    • 请注意,这在人员列表按 key 属性排序的情况下有效(更具体地说,如果具有相同 key 的项目一起显示)。
    • @alexis 是的。你是对的:)我更新了答案。请立即检查。
    【解决方案2】:

    怎么样:

    def get_matches(objs, key):
        d = {}
        for obj in objs:
            d.setdefault(getattr(obj, key), []).append(obj)
        return d
    

    之后[我添加了repr]:

    >>> get_matches(people, "age")
    {27: [{'name': 'nick', 'age': 27}, {'name': 'Janet', 'age': 27}], 
     28: [{'name': 'mike', 'age': 28}, {'name': 'joe', 'age': 28}]}
    

    此提供的一个优点是groupby 通过按连续 值分组来发挥作用。如果这就是你想要的,那就完美了。否则,您必须记住首先按关键功能排序。 (这里的缺点是它不保留键值的出现顺序,尽管如果我们真的在乎,我们可以使用collections.OrderedDict。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-03
      • 1970-01-01
      • 1970-01-01
      • 2020-06-09
      • 1970-01-01
      • 1970-01-01
      • 2018-04-13
      • 2021-11-30
      相关资源
      最近更新 更多