更快捷的方式是什么?删除"我已经附加到我的序列中的项目,所以我不会再次遇到它们?在我的实际代码中,我有更大的单词序列,因此使用.remove(word)
的时间非常昂贵。
我目前的想法:
将单词存储在heapq而不是列表中,并按照我正在使用的启发式对它们进行排序。 (这里的问题是我需要在从序列中删除一个单词后更新启发式值,因此我不相信它有助于时间复杂度)
使用哈希映射来检查单词是否在序列中。在这种情况下,时间复杂度如何?
我有以下代码(为了简单起见,我使用random.choice
,因为我实际上使用启发式来选择下一个单词):
import random
d = {'b': ['bob', 'bun', 'bom'], 'd': ['dob', 'don'], 'm': ['mox']}
print(d)
seq = []
current = 'bob'
seq.append(current)
d[current[:1]].remove(current)
while current[-1:] in d and d[current[-1:]]:
next_ = random.choice(d[current[-1:]])
current = next_
seq.append(current)
d[current[:1]].remove(current)
print(d)
print(seq)
示例输出:
{'b': ['bob', 'bun', 'bom'], 'd': ['dob', 'don'], 'm': ['mox']}
{'b': ['bun'], 'd': ['dob', 'don'], 'm': []}
['bob', 'bom', 'mox']
答案 0 :(得分:1)
如果您希望保持列表不变,但是项目的顺序无关紧要,则需要以下内容。如果您不需要将列表与其所有项目保持一致,则可以更轻松地将项目与最后一项L[-1], L[idx] = L[idx], L[-1]
交换,然后拨打L.pop()
。
实际上不要删除任何东西。保留每个列表的计数,并将该元素与要删除的元素交换并减少计数:
所以[0, []]
是空列表,[3, [1,2,3]]
是删除1
之前的列表,而[2, [3,2,1]]
是之后的列表。
这使得删除项目与Knuth shuffle步骤有效。然后选择一个随机项,您将生成一个介于0和剩余计数之间的数字,然后将该索引与剩余计数减去1的项交换。
生成一个:[len(L)+1, L]
选择一个随机项目:
remaining_count, L = cL
idx = random.randrange(0, remaining_count)
value = L[idx]
L[remaining_count - 1], L[idx] = L[idx], L[remaining_count - 1]
cL[0] = remaining_count - 1
当列表耗尽时, random.randrange会在remaining_count
为-1
时引发ValueError。
结果是在O(1)时间内删除了项目。您可以将列表恢复为原始项目,但也可以通过{(1)}在O(1)中以随机顺序恢复。
如果您需要修剪已删除的元素,可以使用单个方法完成:
cL[0] = len(cL[1])
在remaining_count减1之后删除元素,并且此操作发生在列表的末尾,其成本很低。