2016-11-07 7 views
0

Я хочу сортировать список по первому значению в каждом кортеже, однако мой код не производит никакого реального отсортированного списка, хотя порядок списка меняется. Мой список содержит кортежи со значением для «PlayerCode», который является уникальным ключом для каждого игрока. И «Средние очки», которые являются средним количеством очков, которые игрок оценивает каждую игру. Я хочу отсортировать этот список по «Средним точкам», хотя я не могу понять, как это правильно. Вот мой кодСортировка списка кортежей по первому значению

def getKey(item): 
     return item[0] 
def sortByPoints(): 
    foundPlayers = [] 
    with open ('PlayerList.csv') as csvfile: 
     reader = csv.DictReader(csvfile) 
     for row in reader: 
      foundPlayers.append((row['Average PTS'], row['PlayerCode'])) 
    print(foundPlayers) 
    sortedPlayers = sorted(foundPlayers, key = getKey) 

    print (sortedPlayers) 

Как я уже сказал, это действительно изменяет порядок списка, но не так, как им ищет, не могу я вижу реальную картину, в которой он изменил его. Я использую Python 3.4

Вот выход из двух списков

несортированными: [('7', '1'), ('8', '2'), ('4' , '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' , '8'), ('10', '9'), ('2', '10'), ('4', '11'), ('2', '12'), ('3' ('4', '14'), ('2', '15')]

отсортировано по: [('0', '5'), ('10', ' 7 '), (' 10 ',' 9 '), (' 18 ',' 6 '), (' 2 ',' 10 '), (' 2 ',' 12 '), (' 2 ',' 15 '), (' 28 ',' 4 '), (' 3 ',' 13 '), (' 4 ',' 3 '), (' 4 ',' 11 '), (' 4 ',' 14 '), (' 7 ',' 1 '), (' 8 ',' 2 '), (' 9 ',' 8 ')]

+2

Обратите внимание, что сортировка по первому варианту v alue - это ** default sort ** для кортежей. Помимо этого, без [mcve], непонятно, какова ваша проблема. – jonrsharpe

+1

вы хотите отсортировать, то на основе целочисленного значения, это строки в данный момент, поэтому вы можете просто изменить функцию getKey для возврата int (item [0]) – chatton

+0

Вы можете использовать строки, если хотите, просто отсортируйте используя 'float' - см. http://stackoverflow.com/a/17474264/2178980 (на самом деле вышеприведенный комментарий также будет делать трюк) – Eugene

ответ

0

Проблема в том, что у вас есть строки, и поэтому они сортируют их по алфавиту. Преобразовать в целых числах:

foundPlayers.append((int(row['Average PTS']), int(row['PlayerCode']))) 
0

row['Average PTS'] и row['Player Code'] возвращаемые строки. Python будет сравнивать строки с (возможно) удивительными результатами

>>> '6' > '42' 
True 

Преобразовать row['Average PTS'] и row['Player Code'] использованием int.

0

Вы можете использовать itemgetter импортированные из встроенного модуля operator

Пример кода:

from operator import itemgetter 

tuples = [(10, 3), (1, 4), (5, 4)] 
sorted_tuples = sorted(tuples, key=itemgetter(0)) 

print(sorted_tuples) 

Выход:

[(1, 4), (5, 4), (10, 3)] 
0

Вы можете использовать lambda функцию в качестве ключа для сортировки как:

sorted(my_list, key=lambda x: (int(x[1]), int(x[0]))) 

Здесь:

  • list будет отсортирован на основе содержания в 1 го индекса. При одинаковом значении list будет сортироваться по индексу 0.
  • Также вам необходимо ввести значения в tuple в int. Сортируется лексикографически. Это означает, что для строковых значений «11» появится до «2».

Ниже приведен пример пример:

>>> my_list = [('7', '1'), ('8', '2'), ('4', '3'), ('28', '4'), ('0', '5'), ('18', '6'), ('10', '7'), ('9', '8'), ('10', '9'), ('2', '10'), ('4', '11'), ('2', '12'), ('3', '13'), ('4', '14'), ('2', '15')] 
>>> sorted(my_list, key=lambda x: (int(x[1]), int(x[0])))         
[('7', '1'), ('8', '2'), ('4', '3'), ('28', '4'), ('0', '5'), ('18', '6'), ('10', '7'), ('9', '8'), ('10', '9'), ('2', '10'), ('4', '11'), ('2', '12'), ('3', '13'), ('4', '14'), ('2', '15')] 
0

Вот мой ответ. Я считаю, что в максимально возможной степени сохранить исходный код OP, сделать как можно меньше допущений. Что, если это требование иметь строки? Кроме того, при максимально возможном добавлении импорта. Таким образом, мое решение будет:

def sortByPoints(): 
    foundPlayers = [] 
    with open ('PlayerList.csv') as csvfile: 
     reader = csv.DictReader(csvfile) 
     for row in reader: 
      foundPlayers.append((row['Average PTS'], row['PlayerCode'])) 
    print(foundPlayers) 
    sortedPlayers = sorted(foundPlayers, key=lambda x: float(x[0])) 
    print(sortedPlayers) 

Удалите излишние getKey функцию, и использовать вместо lambda для опрятности. Используя float на всякий случай, это может потребоваться в будущем (поскольку вы используете только для сравнения, использование int ограничивает вас и не имеет преимуществ перед float).

Я также верю в копировать код;)


FYI, чтобы изменить направление:

sortedPlayers = sorted(foundPlayers, key=lambda x: float(x[0]), reverse=True) 

отметить также, что, если намерение действительно для целых чисел только, то вы должны делать так, как все предлагают и конвертируют ваши элементы в int:

def sortByPoints(): 
    foundPlayers = [] 
    with open ('PlayerList.csv') as csvfile: 
     reader = csv.DictReader(csvfile) 
     for row in reader: 
      foundPlayers.append((int(row['Average PTS']), int(row['PlayerCode']))) 
    print(foundPlayers) 
    sortedPlayers = sorted(foundPlayers, key=lambda x: x[0]) 
    print(sortedPlayers) 
Смежные вопросы