Отсортировать список в соответствии с сортировкой по возрастанию второго списка в python

#python #list #sorting

#python #Список #сортировка

Вопрос:

У меня есть два несортированных списка, x и y, следующим образом:

 x = ["a", "b", "c", "d", "e"] 
y = [ 5,   1,   4,   2,   3] 
  

Я хотел бы отсортировать список y два раза, один в порядке возрастания, а затем в порядке убывания. Но при каждой сортировке по y мне нужно соответствующим образом сортировать также соответствующие элементы списка x.
Оба списка имеют одинаковую длину элементов.

Я пытался использовать следующий код, но он работает не так, как ожидалось:

 def sort_list(list1, list2): 

    zipped_pairs = zip(list2, list1) 

    z = [x for _, x in sorted(zipped_pairs)] 
  
    return z 

print(sort_list(x, y)) 
  

Ожидаемый результат: в случае возрастающего порядка

 x = [ "b", "d","e", "c", "a"] 
y = [  1,   2, 3, 4,  5] 
  

Любая помощь?

Комментарии:

1. Это действительно дает ['b', 'd', 'e', 'c', 'a']

2. В чем именно проблема? Вы хотите, чтобы return были отсортированы оба списка, а не только первый?

3. ДА. Мне нужно вернуть оба отсортированных списка, как объяснено в вопросе.

4. Но вы уже знаете, какой будет отсортированная версия y — в этом суть, вот почему вы используете ее для сортировки x .

Ответ №1:

Просто zip y и x — в таком порядке, чтобы вы могли отсортировать результирующие кортежи в естественном порядке по их первому элементу.

Затем вы можете выполнить сортировку и снова заархивировать:

 x = ["a", "b", "c", "d", "e"] 
y = [ 5,   1,   4,   2,   3] 

sorted_y, sorted_x = zip(*sorted(zip(y, x)))

print(sorted_x, sorted_y)
#('b', 'd', 'e', 'c', 'a') (1, 2, 3, 4, 5)
  

В обратном порядке:

 sorted_y, sorted_x = zip(*sorted(zip(y, x), reverse=True))
print(sorted_x, sorted_y)
# ('a', 'c', 'e', 'd', 'b') (5, 4, 3, 2, 1)
  

Комментарии:

1. … и это в два раза быстрее, чем принятый ответ.

2. ДА. Вы правы. Этот ответ правильный и быстрый!!

Ответ №2:

Попробуйте это, используя key параметр в sorted , сохранив большую часть вашего же кода:

 def sort_list(list1, list2):
    zip_pairs=zip(list2, list1)
    z = sorted(zip_pairs, key=lambda x: x[0])
    return z

x, y = zip(*sort_list(x,y))
print(x,y)
  

Вывод:

 (1, 2, 3, 4, 5) ('b', 'd', 'e', 'c', 'a')
  

Ответ №3:

 x = ["a", "b", "c", "d", "e"]
y = [ 5,   1,   4,   2,   3]

def sort_list(list1, list2):
    indexs = {k: v for (k, v) in zip(list2, list1)}
    list2 = sorted(list2)
    list1 = [indexs[i] for i in list2]
    return (list1, list2)

sort_list(x, y)
>>> (['b', 'd', 'e', 'c', 'a'], [1, 2, 3, 4, 5])
  

Ответ №4:

Эта функция работает, я также добавил переменную invert order (инвертировать порядок):

 import numpy as np


def sort_list(list1, list2, invert = False): 

    sorted_idex = np.argsort(list2)
    if invert:
        return list1[sorted_idex[::-1]], list2[sorted_idex[::-1]]
    else:
        return list1[sorted_idex], list2[sorted_idex]


x = np.array(["a", "b", "c", "d", "e"])
y = np.array([ 5,   1,   4,   2,   3])

print(sort_list(x, y)) 
print(sort_list(x, y, invert=True)) 
  

выдача результатов:

 (array(['b', 'd', 'e', 'c', 'a'], dtype='<U1'), array([1, 2, 3, 4, 5]))
(array(['a', 'c', 'e', 'd', 'b'], dtype='<U1'), array([5, 4, 3, 2, 1]))
  

Комментарии:

1. nx[ny.argsort()] где nx=np.array(x) и ny=np.array(y)

Ответ №5:

x и y — это два параметра по умолчанию, предполагающие, что они должны быть в списке. Решение заключается в том, чтобы не использовать zip.

     x = ["a", "b", "c", "d", "e"] 
    y = [ 5,   1,   4,   2,   3]
    X, Y = [], sorted(y)
    for i in Y:
        X.append(x[y.index(i)])
    x,y = X,Y 
    print(x)
    print(y)
  

Ответ №6:

Я попытался объединить оба массива, а затем отсортировать весь на основе второго столбца массива. Предположим, что массив имеет следующий вид:

 arr = [['a',5],['b',1],['c',4],['d',2],['e',3]]
  

Теперь отсортируйте arr переменную, используя 2 столбца следующим образом:

 arr.sort(key = lambda x:x[1])
  

Вывод

 [['b', 1], ['d', 2], ['e', 3], ['c', 4], ['a', 5]]
  

Теперь получите доступ к первым элементам массива