假设我有两个列表:

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

如果我运行list1.sort(),它会把它排序到[1,1,2,3,4],但是否有一种方法让list2同步(所以我可以说项目4属于' 3 ')?因此,期望输出为:

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

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

Basically the nature of this program is, the data comes in a random order (like above), I need to sort it, process it and then send out the results (order doesn't matter but users need to know which result belongs to which key). I thought about putting it in a dictionary first, then sorting list one but I would have no way of differentiating of items in the with the same value if order is not maintained (it may have an impact when communicating the results to users). So ideally, once I get the lists I would rather figure out a way to sort both lists together. Is this possible?


当前回答

如果你需要同步排序超过2个列表,我想建议一个解决方案:

def SortAndSyncList_Multi(ListToSort, *ListsToSync):
    y = sorted(zip(ListToSort, zip(*ListsToSync)))
    w = [n for n in zip(*y)]
    return list(w[0]), tuple(list(a) for a in zip(*w[1]))

其他回答

是什么:

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

sortedRes = sorted(zip(list1, list2), key=lambda x: x[0]) # use 0 or 1 depending on what you want to sort
>>> [(1, 'one'), (1, 'one2'), (2, 'two'), (3, 'three'), (4, 'four')]

我使用senderle给出的答案已经很长时间了,直到我发现了np.argsort。 下面是它的工作原理。

# idx works on np.array and not lists.
list1 = np.array([3,2,4,1])
list2 = np.array(["three","two","four","one"])
idx   = np.argsort(list1)

list1 = np.array(list1)[idx]
list2 = np.array(list2)[idx]

我觉得这个解决方案更直观,而且效果很好。本:

def sorting(l1, l2):
    # l1 and l2 has to be numpy arrays
    idx = np.argsort(l1)
    return l1[idx], l2[idx]

# list1 and list2 are np.arrays here...
%timeit sorting(list1, list2)
100000 loops, best of 3: 3.53 us per loop

# This works best when the lists are NOT np.array
%timeit zip(*sorted(zip(list1, list2)))
100000 loops, best of 3: 2.41 us per loop

# 0.01us better for np.array (I think this is negligible)
%timeit tups = zip(list1, list2); tups.sort(); zip(*tups)
100000 loops, best for 3 loops: 1.96 us per loop

即使np。argsort不是最快的,我发现它更容易使用。

Schwartzian变换。内置的Python排序是稳定的,所以两个1不会造成问题。

>>> l1 = [3, 2, 4, 1, 1]
>>> l2 = ['three', 'two', 'four', 'one', 'second one']
>>> zip(*sorted(zip(l1, l2)))
[(1, 1, 2, 3, 4), ('one', 'second one', 'two', 'three', 'four')]

你可以在sorted()方法中使用key参数,除非你在list2中有两个相同的值。

代码如下:

sorted(list2, key = lambda x: list1[list2.index(x)]) 

它根据list1中的对应值对list2进行排序,但请确保在使用此方法时,list2中的任何两个值都不相等,因为list.index()函数给出了第一个值

一种方法是通过对单位[0,1,2,..n]进行排序来跟踪每个索引的去向。

这适用于任何数量的列表。

然后移动每个项目到它的位置。使用拼接是最好的。

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

index = list(range(len(list1)))
print(index)
'[0, 1, 2, 3, 4]'

index.sort(key = list1.__getitem__)
print(index)
'[3, 4, 1, 0, 2]'

list1[:] = [list1[i] for i in index]
list2[:] = [list2[i] for i in index]

print(list1)
print(list2)
'[1, 1, 2, 3, 4]'
"['one', 'one2', 'two', 'three', 'four']"

注意,我们可以在不排序的情况下迭代列表:

list1_iter = (list1[i] for i in index)