2014-12-08 2 views
1

Я все еще учусь Python, и я пытался разобраться с этой проблемой в течение нескольких часов, но как-то не может получить его работу: Предположим, у нас есть список кортежей, содержащих имена и марки:Python: Сортировка списка, содержащий кортежи

[("Mark", [5,4,1,2,4,3]), ("John", [1,2,3,1,2,1]), ("Patrick", [1,3,5,1,2,4])] 

И мы хотим, чтобы получить этот результат:

[("John", [1,2,3,1,2,1]), ("Patrick", [1,3,5,1,2,4]), ("Mark", [5,4,1,2,4,3])] 

, где первоначальный список сортируется в порядке возрастания студентов знаков счет (предположим, что мы получаем метки оценка, отбрасывая самую высокую отметку и добавляя все остальные метки вместе). I.e. У Джона есть отметки 1,2,3,1,2,1, поэтому мы отбрасываем метку 3 и добавляем 1 + 2 + 1 + 2 + 1 вместе, что дает нам 7.

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

def sortedFinalRes(input): 
finalRes = 0 
sortedRes = [] 
b = [] 
for i in range(0, len(input)): 
    total = 0 
    a = sorted(input[i][1], key = lambda x: x) 
    a.pop() 
    sortedRes += input[i][0], a 
    total = sum(sortedRes[i*2+1]) 
    b += (sortedRes[i*2], total) 
    c = sorted(b, key = lambda x: str(x)) 
print(sortedRes) 
print(b) 

, где я в основном на первых сортировки марок каждого студента, так что я могу после этого отбрасывать самый высокий с помощью поп(), а затем я просуммировать все остальные из них, что дает мне знаки оценка , Затем я сортирую его по меткам, но результат нужно сортировать, но с оригинальными знаками, а не с меткой. Любые идеи оценены! Приветствия

ответ

5

Мы можем определить функцию подсчета очков, как это:

def score(x): sum(x) - max(x)  

Это вычисляет ваши так называемые «знаки забьет» путем суммирования баллов и выбрасывая максимальный балл. Затем мы используем его в качестве ключа для сортировки, убедившись, чтобы дать ему второй элемент кортежа:

In [4]: sorted(d, key=lambda x: score(x[1]))                             
Out[4]: 
[('John', [1, 2, 3, 1, 2, 1]), 
('Patrick', [1, 3, 5, 1, 2, 4]), 
('Mark', [5, 4, 1, 2, 4, 3])] 
+1

отличный ответ и промахните его прямо передо мной: P –

+1

Почему двойные лямбды? Lambdas никогда не должен быть привязан к переменным, он пропускает точку. Как насчет 'sorted (d, key = lambda x: sum (x) - max (x))' вместо? – tdelaney

+2

@tdelaney - 'sorted (d, key = lambda x: sum (x [1]) - max (x [1]))', если быть точным. 'x' будет кортежей в списке. Но хорошая идея в целом. – iCodez

3
def sort_key(item): 
    name,scores = item 
    return sum(scores)-max(scores) 
print sorted(students,key=sort_key) 

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

1

вы можете отказаться от максимального значения по sorted(x[1])[:-1], что первый сортировать список и срез от начала до самого высокого:

>>> sorted (l,key=lambda x : sum(sorted(x[1])[:-1])) 
[('John', [1, 2, 3, 1, 2, 1]), ('Patrick', [1, 3, 5, 1, 2, 4]), ('Mark', [5, 4, 1, 2, 4, 3])] 

ответы бенчмарк:

>>> s="""l=[("Mark", [5,4,1,2,4,3]), ("John", [1,2,3,1,2,1]), ("Patrick", [1,3,5,1,2,4])] 
... sorted (l,key=lambda x : sum(sorted(x[1])[:-1]))""" 
>>> timeit.timeit(stmt=s, number=100000) 
0.407818078994751 

>>> s="""l=[("Mark", [5,4,1,2,4,3]), ("John", [1,2,3,1,2,1]), ("Patrick", [1,3,5,1,2,4])] 
... sorted(l, key=lambda x: sum(x[1]) - max(x[1]))""" 
>>> timeit.timeit(stmt=s, number=100000) 
0.3033828830718994 

>>> s="""l=[("Mark", [5,4,1,2,4,3]), ("John", [1,2,3,1,2,1]), ("Patrick", [1,3,5,1,2,4])] 
... def sort_key(item): 
...  name,scores = item 
...  return sum(scores)-max(scores) 
... sorted(l,key=sort_key)""" 
>>> timeit.timeit(stmt=s, number=100000) 
0.2999439334869385 

Как вы можете видеть, нет никакой разницы между всеми ответами, так как ответ Йорана Бисли является лучшим!

+0

Это фактически 'nlogn', тогда как другое решение -' n' – iruvar

+0

@ 1_CR, как вы думаете, что использование 'max' внутри' sorted' имеет 'n' порядок? – Kasramvd

+0

На самом деле, если 'n' - размер внешнего списка, а' m' - размер внутреннего, это решение - 'O (nm log m + n log n)', тогда как решение с 'max' является' O (nm + n log n) ', я считаю. – jme

Смежные вопросы