如何以完全相同的方式对两个列表(相互引用)进行排序

发布于 2021-01-29 19:30:54

说我有两个清单:

list1 = [3, 2, 4, 1, 1]
list2 = ['three', 'two', 'four', 'one', 'one2']

如果我运行list1.sort(),它将对其进行排序,[1,1,2,3,4]但是还有没有一种list2同步的方法(因此我可以说item4属于'three')?因此,预期输出为:

list1 = [1, 1, 2, 3, 4]
list2 = ['one', 'one2', 'two', 'three', 'four']

我的问题是我有一个非常复杂的程序,可以很好地处理列表,但是我有点需要开始引用一些数据。我知道这对字典来说是一个完美的情况,但是我在处理过程中尽量避免使用字典,因为我确实需要对键值进行排序(如果必须使用字典,我知道如何使用它们)。

基本上,该程序的本质是,数据按随机顺序出现(如上),我需要对其进行排序,处理然后发送结果(顺序无关紧要,但是用户需要知道哪个结果属于哪个结果)键)。我考虑过先将其放入字典中,然后再对列表进行排序,但是如果不保持顺序(如果将结果传达给用户,可能会产生影响),我将无法区分具有相同值的项。因此,理想情况下,一旦获得列表,我宁愿想出一种将两个列表排序在一起的方法。这可能吗?

关注者
0
被浏览
205
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    解决此问题的一种经典方法是使用“装饰,排序,未装饰”习惯用法,使用python的内置zip函数特别简单:

    >>> list1 = [3,2,4,1, 1]
    >>> list2 = ['three', 'two', 'four', 'one', 'one2']
    >>> list1, list2 = zip(*sorted(zip(list1, list2)))
    >>> list1
    (1, 1, 2, 3, 4)
    >>> list2 
    ('one', 'one2', 'two', 'three', 'four')
    

    这些当然不再是列表,但是如果需要的话,很容易纠正:

    >>> list1, list2 = (list(t) for t in zip(*sorted(zip(list1, list2))))
    >>> list1
    [1, 1, 2, 3, 4]
    >>> list2
    ['one', 'one2', 'two', 'three', 'four']
    

    值得一提的是,以上可能会为简洁而牺牲速度。就地版本,占用3行,在我的机器上,对于较小的列表来说,快了一点:

    >>> %timeit zip(*sorted(zip(list1, list2)))
    100000 loops, best of 3: 3.3 us per loop
    >>> %timeit tups = zip(list1, list2); tups.sort(); zip(*tups)
    100000 loops, best of 3: 2.84 us per loop
    

    另一方面,对于较大的列表,单行版本可能会更快:

    >>> %timeit zip(*sorted(zip(list1, list2)))
    100 loops, best of 3: 8.09 ms per loop
    >>> %timeit tups = zip(list1, list2); tups.sort(); zip(*tups)
    100 loops, best of 3: 8.51 ms per loop
    

    正如Quantum7指出的那样,[SF的建仍然要快一些,但可能只会更快一些,因为Python内部在所有基于键的排序中使用了完全相同的DSU习惯用法。它只是在接近裸机的地方发生。(这表明zip例程的优化程度如何!)

    我认为zip基于方法的灵活性更高,可读性更好,所以我更喜欢它。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看