具有唯一属性的对象列表

23

我有一个对象列表,每个对象都有一个特定的属性。该属性不是唯一的,我希望最终得到的对象列表是整个列表的子集,使得所有特定属性都是唯一的集合。

例如,如果我有四个对象:

object1.thing = 1
object2.thing = 2
object3.thing = 3
object4.thing = 2

我希望最终可以选择以下任一种方案:

[object1, object2, object3]
[object1, object3, object4]

最终列表中出现的确切对象并不重要,只要它们特定属性的列表是唯一的。

编辑:澄清一下,本质上我想要的是一个以该特定属性为键的集合。


1
可能是[如何使用关键词获取唯一列表:Python](https://dev59.com/jWkw5IYBdhLWcg3wQoSm)的重复内容。 - Georgy
2个回答

28

您可以使用列表解析和集合:

objects = (object1,object2,object3,object4)
seen = set()
unique = [obj for obj in objects if obj.thing not in seen and not seen.add(obj.thing)]

上述代码等同于:

seen = set()
unique = []
for obj in objects:
    if obj.thing not in seen:
        unique.append(obj)
        seen.add(obj.thing)

2
这篇文章因为使用集合比字典更好地传达了任务而受到点赞。两者都使用了 Python 中“可哈希”的对象,因此在功能上是等效的。但是如果我阅读你的代码,集合会立即告诉我“他需要一个唯一的东西列表”,而字典则告诉我“他需要映射数据”,而在这种情况下会产生误导。 - Dave
5
这是一个更好的解决方案,但是这段代码会导致Python 2和3中的语法错误。正确的语法是:unique = [obj for obj in objects if obj.thing not in seen and not seen.add(obj.thing) is None] - GDR

16
你可以创建一个字典,其键是对象的“事物”,值是对象本身。
d = {}
for obj in object_list:
    d[obj.thing] = obj
desired_list = d.values()

11
dict((obj.thing, obj) for obj in object_list).values() 翻译为:将一个对象列表中的每个对象的某个属性作为键值对的键,创建一个字典,然后返回该字典的所有值。 - Fred Foo
我确实喜欢那个,但是我总是很难阅读字典解析,并且我想要清楚地表明我在做什么。 - Blair
2
Python 3 让代码更漂亮:{obj.thing: obj for obj in object_list}(但是从 values 返回的是一个视图,而不是列表)。 - Fred Foo
1
被踩了。虽然这是一种常见的做法,但我认为这样使用字典是不好的做法。这正是集合被构建的确切用例,应该使用它们。 - Dave
2
使用字典推导式:{ obj.thing : obj for obj in object_list}.values()。我认为这比上面得到的最高票评论更易读。 - Harsh Trivedi
发现对于非常大的对象列表,与使用Ashwini的列表方法相比,这种方法的速度显着提高了(在我的情况下高达2000倍)。 - Jérôme Bau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接