Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 检查对象属性是否存在于对象列表中_Python - Fatal编程技术网

Python 检查对象属性是否存在于对象列表中

Python 检查对象属性是否存在于对象列表中,python,Python,我有一个具有不同属性的对象和一个包含这些对象的列表 在向列表中添加对象之前,我想检查列表中是否存在此新对象的属性 此属性是唯一的,因此这样做是为了确保列表中的每个对象都是唯一的 我会这样做: for post in stream: if post.post_id not in post_list: post_list.append(post) else: # Find old post in the list and replace it 但显然

我有一个具有不同属性的对象和一个包含这些对象的列表

在向列表中添加对象之前,我想检查列表中是否存在此新对象的属性

此属性是唯一的,因此这样做是为了确保列表中的每个对象都是唯一的

我会这样做:

for post in stream:
    if post.post_id not in post_list:
        post_list.append(post)
    else:
        # Find old post in the list and replace it

但显然,第2行不起作用,因为我正在将
post\u id
与对象列表进行比较

保留一个单独的集合,向其中添加属性,然后根据该集合测试下一个值:

ids_seen = set()
for post in stream:
    if post.post_id not in ids_seen:
        post_list.append(post)
        ids_seen.add(post.post_id)
另一个选项是创建第一个,ID作为键:

posts = OrderedDict((post.post_id, post) for post in stream)
post_list = list(posts.values())
这将为给定的
id
保留最近看到的
post
引用,但您仍然只保留唯一的id

如果顺序不重要,只需使用常规词典:

posts = {post.post_id: post for post in stream}
post_list = list(posts.values())
如果您使用的是Python 3.6或更高版本,那么在更新CPython实现以保留输入顺序时,顺序将保持不变,并且在Python 3.7中,此功能已成为语言规范的一部分

无论您做什么,都不要使用单独的列表来测试
post.id
,因为每次检查id是否存在时都需要O(N)个时间,其中N是最后流中的项目数。结合O(N)类检查,这种方法需要O(N**2)个二次时间,这意味着输入项的数量每增加10倍,处理它们的时间也会增加100倍

但是当使用集合或字典时,测试id是否已经存在只需要O(1)个常量时间,因此检查很便宜。这使得一个完整的处理循环需要O(N)个线性时间,这意味着它需要的时间与您拥有的输入项的数量成正比。

这应该可以工作

for post in stream:
    if post.post_id not in [post.post_id for post in post_list]:
        post_list.append(post)

如果您可以控制
post
类,那么您可以创建一个
\uuuuuuuuuuuuuuuuu散列
方法并在那里使用
post\u id
的值,然后只需执行
post\u list=set(stream)
@Peter:考虑到这不会保持顺序<代码>列表(OrderedDict.fromkeys(stream))会按照第一次看到的id的顺序保存输入。啊,是的,公平地说,从他措辞的方式来看,我认为顺序并不重要,但我并没有认真考虑:这是非常低效的,因为
不在
必须对您生成的列表进行完整扫描。您还可以在每次迭代中重新生成
post\u id
列表。这种组合是致命的,使得这成为一种只需要O(N**3)线性时间的O(N**3)二次方法。对于1000个项目,你的方法需要的时间大约是O(N)线性方法的100万倍。因此,如果你有耐心的话,它应该是有效的。当输入序列变长时(10k项、慢1亿倍、100k项、慢100亿倍等),这会迅速消耗时间。