最有效的方法是添加一个项目,同时从一个固定长度的列表中删除一个项目

2024-05-29 04:31:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在分析一些可能有重复的数据。为了摆脱它们,我使用一个小列表,其中包含最后五个不重复的项,并检查当前项是否不在列表中。我有一个可行的解决办法,但应该有更好的办法。有什么想法吗?你知道吗

我目前的代码实现了这一点:

activities = []
index = 0

# Open file
# Loop lines (each line is an activity)
# Parse line to activity object

if activity not in activities:
    # session is part of SQLAlchemy but this isn't that important
    self.session.add(activity)

# The part from here on is the one I want changed
if len(activities) == 5:
    activities.pop(index)

activities.insert(index, activity)

if index == 4:
    index = 0
else:
    index = index + 1

编辑:问题不在于删除此列表中的重复项。这只是为了检查新活动是否在最后添加的活动之一中。我正在解析大量数据,并对照所有旧活动检查新活动,这将是一个巨大的瓶颈。数据是按日期排序的,并且在最后几个活动中确实可以有一个副本(所以我检查最后5个)。得到唯一的值不是问题,我只是要求一个解决方案,做同样的事情,我已经做了,但会更好。你知道吗


Tags: 数据代码列表indexifissessionline
3条回答

您可以使用^{}进行过滤。它将保留原始顺序,以便结果按第一次出现的顺序排列:

from collections import OrderedDict

items = [3, 5, 6, 2, 5, 6, 1, 7, 8, 2, 3, 6]
items = OrderedDict((x, True) for x in items).keys() # [3, 5, 6, 2, 1, 7, 8]

答案是使用一种不同的数据结构——一种专门为此目的而定制的数据结构。如果新项目不是最近五个元素中的一个的副本,那么您的方法就失败了。你知道吗

而是使用set。你知道吗

使用__hash__方法将每个活动解析为类的对象,然后在解析时将每个新活动添加到集合中。这将留给您一个只包含输入中唯一对象的集合。你知道吗

解析完输入后,可以将set转换为list。你知道吗

s = set()
while more_data_to_parse():
    s.add(parse_next_object())
activities = list(s)

例如:

>>> s = set()
>>> for i in [1, 2, 3, 2, 3, 4, 5, 6, 1, 6]:
...     s.add(i)
... 
>>> activities=list(s)
>>> activities
[1, 2, 3, 4, 5, 6]
>>> 

结果列表的顺序与原始输入的顺序不同,但这可以通过简单的排序来解决。你知道吗

collections.deque使用有限的maxlen将有效 在insert+delete操作中

from collections import deque

activities = deque(maxlen=5)
# if len(activities) == 5 then the leftmost item will be removed before the push
activities.push(activity)

但是# some code in-between可能需要一些更改,因为现在的数据是这样的 在每一步上移动,改变指数。你知道吗

或者

您可以在activities前面加上Nones,然后只需

activities = [None] * 5
index = 0

# some code in-between

activities[index] = activity

if index == 4:
    index = 0
else:
    index = index + 1

假设您没有任何活动)

相关问题 更多 >

    热门问题