Python сортирует два списка
Я пытаюсь сортировать два списка вместе:
list1 = [1, 2, 5, 4, 4, 3, 6]
list2 = [3, 2, 1, 2, 1, 7, 8]
list1, list2 = (list(x) for x in zip(*sorted(zip(list1, list2))))
В любом случае, это дает мне выход
list1 = [1, 2, 3, 4, 4, 5, 6]
list2 = [3, 2, 7, 1, 2, 1, 8]
в то время как я хотел бы сохранить начальный порядок для равного числа 4 в первом списке: я хочу
list1 = [1, 2, 3, 4, 4, 5, 6]
list2 = [3, 2, 7, 2, 1, 1, 8]
Что мне делать? Я бы не хотел использовать цикл для сортировки пузырьков. Любая помощь была оценена.
Ответы
Ответ 1
Используйте параметр key
для вашего типа, который сравнивает только первый элемент пары. Поскольку сортировка Python стабильна, это гарантирует, что порядок вторых элементов останется таким же, когда первые элементы равны.
>>> from operator import itemgetter
>>> [list(x) for x in zip(*sorted(zip(list1, list2), key=itemgetter(0)))]
[[1, 2, 3, 4, 4, 5, 6], [3, 2, 7, 2, 1, 1, 8]]
Что эквивалентно:
>>> [list(x) for x in zip(*sorted(zip(list1, list2), key=lambda pair: pair[0]))]
[[1, 2, 3, 4, 4, 5, 6], [3, 2, 7, 2, 1, 1, 8]]
Ответ 2
Трюк здесь заключается в том, что когда Python выполняет сопоставления кортежей, он сравнивает элементы по порядку слева направо (например, (4, 1) < (4, 2)
, что является причиной того, что вы не получаете требуемый заказ в своем конкретном случае). Это означает, что вам нужно передать аргумент key
в функцию sorted
, которая сообщает ему использовать только первый элемент кортежа пары как его выражение сортировки, а не весь набор.
Это гарантирует сохранение желаемого заказа, потому что:
сортировки гарантированно стабильны. Это означает, что, когда несколько записей имеют один и тот же ключ, их первоначальный порядок сохраняется.
(источник)
>>> list1 = [1, 2, 5, 4, 4, 3, 6]
>>> list2 = [3, 2, 1, 2, 1, 7, 8]
>>>
>>> list1, list2 = (list(x) for x in zip(*sorted(zip(list1, list2), key=lambda pair: pair[0])))
>>>
>>> print list1
[1, 2, 3, 4, 4, 5, 6]
>>> print list2
[3, 2, 7, 2, 1, 1, 8]
Ответ 3
В вашем коде сортировка выполняется на основе первого и второго элементов кортежей, поэтому результирующие элементы второго списка находятся в отсортированном порядке для тех же элементов первого списка.
Чтобы избежать сортировки на основе второго списка, просто укажите, что в сравнении кортежей следует использовать только элементы из первого списка:
>>> from operator import itemgetter
>>> list1, list2 = (list(x) for x in zip(*sorted(zip(list1, list2),key=itemgetter(0))))
>>> list1, list2
([1, 2, 3, 4, 4, 5, 6], [3, 2, 7, 2, 1, 1, 8])
itemgetter(0)
берет первый элемент из каждого кортежа, который принадлежит первому списку.