模拟排序中的数组交换

时间:2015-05-24 04:19:36

标签: python list sorting

l = [0, 1, 3, 2]

l2 = ['foo', 3, 'bar', 10]

如果我说sorted(l),我会得到[0, 1, 2, 3]。它将交换最后两个元素。

如何将同一行交换应用于l2?即,我希望l2['foo', 3, 10, 'bar']

2 个答案:

答案 0 :(得分:6)

您可以使用zip,解包元组和列表理解来实现结果:

[y for x, y in sorted(zip(l, l2))]

答案 1 :(得分:4)

<强> TL; DR

>>> l, l2 = zip(*sorted(zip(l, l2)))
>>> list(l)
[0, 1, 2, 3]
>>> list(l2)
['foo', 3, 10, 'bar']

<强>解释

  1. zip两个列表一起

    >>> list(zip(l, l2))
    [(0, 'foo'), (1, 3), (2, 10), (3, 'bar')]
    
  2. 然后对它们进行排序,(因为我们从zip得到元组,元组的第一个元素将首先进行比较,只有它们相同时,第二个元素才会被比较。所以排序有效发生值为l

    >>> sorted(zip(l, l2))
    [(0, 'foo'), (1, 3), (2, 10), (3, 'bar')]
    
  3. 然后解压缩,

    >>> list(zip(*sorted(zip(l, l2))))
    [(0, 1, 2, 3), ('foo', 3, 10, 'bar')]
    

    您实际上可以解压缩ll2,就像这样

    >>> l, l2 = zip(*sorted(zip(l, l2)))
    >>> l, l2
    ((0, 1, 2, 3), ('foo', 3, 10, 'bar'))
    >>> list(l)
    [0, 1, 2, 3]
    >>> list(l2)
    ['foo', 3, 10, 'bar']
    
  4. 替代方法

    您实际上可以将值与当前索引一起排序,然后您可以像这样重建值

    >>> l = [0, 1, 3, 2]
    >>> l2 = ['foo', 3, 'bar', 10]
    >>> l_s = sorted((value, idx) for idx, value in enumerate(l))
    >>> l_s
    [(0, 0), (1, 1), (2, 3), (3, 2)]
    >>> l = [value for value, idx in l_s]
    >>> l
    [0, 1, 2, 3]
    >>> l2 = [l2[idx] for value, idx in l_s]
    >>> l2
    ['foo', 3, 10, 'bar']