【问题标题】:Sort a list with duplicates based on another list with same items but different order根据具有相同项目但顺序不同的另一个列表对具有重复项的列表进行排序
【发布时间】:2021-03-04 18:36:04
【问题描述】:

我有两个这样的字符串列表(两个列表有相同的项目,但顺序不同):

lst1 = ['C', 'H', 'H', 'H', 'C', 'O', 'O', 'H']
lst2 = ['H', 'H', 'C', 'O', 'H', 'O', 'H', 'C']

要根据lst1lst2 进行排序,我想为lst1 中的每个项目找到lst2 索引。对于重复项,我想采用尚未采用的最小索引

我想知道获取这样一个索引列表的最快方法:

ids = [2, 0, 1, 4, 7, 3, 5, 6]

然后我可以对lst2 进行排序

newlst2 = [lst2[i] for i in ids]

由于有重复,获取列表索引的正常方式

ids = [lst2.index(x) for x in lst1]

会给出错误的结果

ids = [2, 0, 0, 0, 2, 3, 3, 0]

有什么建议吗?

【问题讨论】:

  • 预期结果是什么?
  • ids = [2, 0, 1, 4, 7, 3, 5, 6] 是预期结果
  • “获取列表索引ids = [lst2.index(x) for x in lst1] 的正常方式”不是正常的方式。这是一种非常低效的方式。您通常应该避免这种情况。
  • 您究竟为什么要以这种复杂的方式计算newlst2?还是根本没有?你不只是得到与lst1 相同的东西吗?
  • 因为实际上字符串是由 Molecule 类的属性给出的。您可能会注意到,字符串代表化学元素。我想根据名称“CH3COOH”的顺序对 CH3COOH 分子的原子进行排序。

标签: python list sorting indexing duplicates


【解决方案1】:

您可以收集每个值的索引,然后使用这些集合。花费 O(n) 时间。

from collections import defaultdict, deque

indexes = defaultdict(deque)
for i, x in enumerate(lst2):
    indexes[x].append(i)

ids = [indexes[x].popleft() for x in lst1]

【讨论】:

  • 有了你所有的导入,你的速度比我幼稚的 O(n2) 慢 2.5 倍 - 大 O 符号只是故事的一半!
  • @ReblochonMasque 好的,那么这里有一个更快的解决方案:ids = [2, 0, 1, 4, 7, 3, 5, 6]
  • @ReblochonMasque 另外,你是如何测量它的?我现在也尝试了这些小列表,但我的速度只慢了大约 1.2 倍。
  • 问题是“最快的方式”,慢1.2倍,更慢!虽然无法击败ids = [2, 0, 1, 4, 7, 3, 5, 6]
  • @ReblochonMasque 将列表加倍,我的已经是您的 1.5 倍,长度为 96(略低于您现在在回答中提到的 100),我的大约速度提高 5.5 倍。
【解决方案2】:

虽然理论上不是最快的O(n2),但对于在分子中排序原子位置的用例,如 cmets 所示(假设分子大小为样本顺序:10ish 个原子),这种简单的方法,使用内置函数可能比其他需要多次导入外部库的更复杂的答案 (O(n)) 更快。

您可以将lst1start)的每个元素索引到lst2model)中,并将lst2中的元素替换为None

start = ['C', 'H', 'H', 'H', 'C', 'O', 'O', 'H']
model = ['H', 'H', 'C', 'O', 'H', 'O', 'H', 'C']

res = []
for elt in start:
    idx = model.index(elt)
    res.append(idx)
    model[idx] = None
    
res   # [2, 0, 1, 4, 7, 3, 5, 6]

【讨论】:

  • 问题是“最快的方法”,这只是 O(n^2)。
  • 是“外部库”应该引用collections,它是one库的一部分,Python的标准 i> 图书馆?
猜你喜欢
  • 2022-01-04
  • 1970-01-01
  • 2018-01-03
  • 2018-09-15
  • 1970-01-01
  • 1970-01-01
  • 2019-02-16
  • 2021-02-12
  • 2012-08-27
相关资源
最近更新 更多