【发布时间】:2021-12-04 03:28:19
【问题描述】:
我有一个工作流程来处理列表,并跟踪我在字典中看到的列表 - 因为当我找到已经看到的列表时,我可以传递它。需要注意的是,具有相同元素的两个列表以不同的方式排列被认为是重复的。所以举个简单的整数列表例子:[3, 1, 5, 6] 和[5, 3, 6, 1] 是等价的。
我的做法是,将tuple(sorted(L)) 放入我的字典中。所以对于上面的例子seen 看起来像:
seen = {..., (1, 3, 5, 6): 1, ...}
这具有对我可能需要处理的每个列表进行恒定时间查找的好处。然而问题是,为了检查给定列表是否在seen 中,我必须对其执行tuple(sorted(L))。事实证明,对于大量数据,这变得令人望而却步,以至于占用了我整个过程总时间的 50% 以上。
我想以某种方式使用collections.Counter - 因为Counter[3, 1, 5, 6] 和Counter[5, 3, 6, 1] 将评估相等。但是 Counter 对象不能用作字典键。如何保持我的字典查找,但不执行上述排序操作?提前致谢。
编辑:在查看使用frozenset 的建议时,我意识到我遗漏了一件重要的事情,那就是元素可以重复。因此,虽然上面的两个列表比较相等,但 [3, 1, 5, 6] 和 [3, 3, 1, 5, 6, 6] 需要被视为不同的。由于frozenset 操作会删除重复项,因此这里不是一个选项。
【问题讨论】:
-
对此完全不确定,但
frozenset会减少时间消耗吗?同样,我不知道实现细节。 -
@j1-lee 我怀疑最终会花费时间的排序、内存分配和过线性时间复杂度。
-
@Vatine 很高兴知道!谢谢:)
-
您的列表和计数器有多大?
-
我不认为将元组设置为 dict 键是一个好主意。也许将它们转换为字符串?这样,不同顺序的元组字符串将被视为不重复。