我有一个具有不同属性的对象和一个包含这些对象的列表。
在将对象添加到列表之前,我想检查列表中是否存在此新对象的属性。
此属性是唯一的,因此可以确保列表中的每个对象都是唯一的。
我会做这样的事情:
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_id
与对象列表进行比较。
答案 0 :(得分:1)
保留一个单独的集合,向该集合添加属性,然后针对该集合测试下一个值:
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)
另一种选择是先创建一个ordered dict,并将id作为键:
posts = OrderedDict((post.post_id, post) for post in stream)
post_list = list(posts.values())
这将为给定的post
保留最近看到的id
参考,但是您仍然会 only 唯一的ID。
如果排序不重要,只需使用常规的字典理解即可:
posts = {post.post_id: post for post in stream}
post_list = list(posts.values())
如果您使用的是Python 3.6或更高版本,则在更新CPython实现以保留输入顺序时,该顺序将始终保留 ,并且在Python 3.7中,此功能已成为语言规范的一部分。
无论您做什么,都不要使用单独的 list 来测试post.id
,因为每次检查都需要O(N)时间 查看ID是否存在,其中N是最后流中的项目数。结合使用O(N)这样的检查,该方法将花费O(N ** 2)二次时间,这意味着输入项数量每增加10倍,处理时间也要多100倍全部。
但是当使用集合或字典时,测试id是否已经存在只需要O(1)恒定时间,因此检查很便宜。这样一来,整个处理循环就需要O(N)个线性时间,这意味着所花费的时间与您拥有的输入项的数量成正比。
答案 1 :(得分:-1)
这应该有效
for post in stream:
if post.post_id not in [post.post_id for post in post_list]:
post_list.append(post)