Подтвердить что ты не робот

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]

Что мне делать? Я бы не хотел использовать цикл для сортировки пузырьков. Любая помощь была оценена.

4b9b3361

Ответ 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) берет первый элемент из каждого кортежа, который принадлежит первому списку.