2015-01-26 5 views
1

У меня есть два списка;Применить преобразование к списку на основе сортировки другого списка

A = ['red', 'green', 'blue', 'white', 'black'] 
B = ['22', '34', '7', '3', '850'] 

Я хотел бы отсортировать список B от максимального значения до минимального значения, а затем сортировать список А, основанный на преобразовании применяется к списку B. То есть;

A = ['black', 'green', 'red', 'blue', 'white'] 
B = ['850', '34', '22', '7', '3'] 
+0

Это интересное упражнение, то, что вы пробовали до сих пор? – Scironic

+2

Строго говоря, вы неправильно отсортировали список 'B', поскольку они являются строками, и вы отсортировали их численно. –

ответ

5

Самый простой способ, чтобы пронестись их, сортировать их по второму компоненту, а затем распаковать их:

ab = zip(A, B) 
ab.sort(key=lambda values: int(values[1]), reverse=True) 
A, B = zip(*ab) 
+0

После применения 'A, B = zip (* ab)', A и B больше не являются списками, а 1-кортежи, правильно? Помимо выполнения 'A = list (A)' и 'B = list (B)' в последующих строках, есть ли более простой и быстрый способ сделать это? – p014k

+0

Не совсем, кроме понимания списка, упомянутого в других ответах, но это не работает, если вам нужны оба отсортированных списка. –

2

zip их, чтобы создать последовательность кортежей, а затем использовать список понимание для извлечения первое значение из каждого кортежа в отсортированном порядке.

A key argument can be passed to sorted, который позволяет сортировать по функциям. В приведенном ниже примере мы сортируем с помощью lambda function, который возвращает второе значение из ваших комбинированных кортежей, преобразованных в целое число.

Обратите внимание, что существует разница между сортировки строк и сортировки чисел, и как таковой вы должны преобразовать значения из B с помощью int, если вы не хотите, чтобы это по каким-то причинам, то вы можете удалить int вызов в лямбда функция.

A = ['red', 'green', 'blue', 'white', 'black'] 
B = ['22', '34', '7', '3', '850'] 

C = zip(A, B) 

D = [i for i, _ in sorted(C, key=lambda x:int(x[1]), reverse=True)] 

print(D) 
# ['black', 'green', 'red', 'blue', 'white'] 
0
sorted_by_second_list = [x[0] for x in sorted(zip(A,B),key=lambda tup: int(tup[1]))] 

зип создаст список кортежей, используемый с лямбда в функции сортировки

-1
a=['red','green','blue','white','black'] 
b=[22,34,7,3,850] 
c=zip(a,b) 
print c 
[('red', 22), ('green', 34), ('blue', 7), ('white', 3), ('black', 850)] 
from operator import itemgetter 
sorted(c, key=itemgetter(1), reverse=True) 
[('black', 850), ('green', 34), ('red', 22), ('blue', 7), ('white', 3)] 
+0

Некоторый дополнительный комментарий к вашему коду был бы приятным ... – achedeuzot

1

Помимо встроенной функции zip & sort, как ответил @DanielRoseman, вы можете использовать numpy модуль сорт:

In [116]: import numpy as np 
    ...: A = ['red', 'green', 'blue', 'white', 'black'] 
    ...: B = ['22', '34', '7', '3', '850'] 
    ...: A = np.asarray(A) 
    ...: B = np.asarray(B) 
    ...: iB = np.asarray(map(int, B)) 
    ...: idx = iB.argsort()[::-1] #get indices in reverse order 
    ...: sa = A[idx] 
    ...: sb = B[idx] 

In [117]: print sa, sb 
['black' 'green' 'red' 'blue' 'white'] ['850' '34' '22' '7' '3'] 

numpy более эффективен при сортировке ваших списков больших размеров.

Для теста:

In [97]: a = np.random.randint(1000, size=10000) 
    ...: b = np.random.randint(1000, size=10000) 

In [99]: %%timeit 
    ...: idx = b.argsort()[::-1] 
    ...: sa = a[idx] 
    ...: sb = b[idx] 
    ...: 
1000 loops, best of 3: 648 µs per loop 

In [100]: %%timeit 
    ...: ab = zip(a, b) 
    ...: ab.sort(key=lambda values: int(values[1]), reverse=True) 
    ...: sa, sb = zip(*ab) 
    ...: 
100 loops, best of 3: 10.1 ms per loop 
Смежные вопросы