#python #python-3.x #list #sorting
#python #python-3.x #Список #сортировка
Вопрос:
Я пытаюсь написать программу, которая получает данные из базы данных и печатает их отсортированными. Когда я сортирую свой окончательный список, у меня возникает эта ошибка:
employee_list.pop (employee_list.index (max_weight_path))
ValueError: ('mahdi', 90, 190) is not in list
но это мой примерный список:
[('amin', 75, 180), ('mahdi', 90, 190), ('mamad', 75, 175), ('ahmad', 60, 175)]
и, наконец, мой фрагмент кода:
sorted_employee = []
max_weight = 0
max_weight_path = ''
i = len (employee_list)
for z in range (i):
for x in employee_list:
if x[2] > max_weight:
max_weight = x[2]
max_weight_path = x
elif x[2] == max_weight:
if x[1] < max_weight_path[1]:
max_weight_path = x
sorted_employee.append (max_weight_path)
employee_list.pop (employee_list.index (max_weight_path))
Ответ №1:
Сортировка списка с помощью .sort
Вам не нужно кодировать свой собственный алгоритм сортировки, есть довольно эффективный встроенный: сортировка документации Python: КАК.
from operator import itemgetter
employee_list = [('amin', 75, 180), ('mahdi', 90, 190), ('mamad', 75, 175), ('ahmad', 60, 175)]
employee_list.sort(key=itemgetter(2))
print(employee_list)
# [('mamad', 75, 175), ('ahmad', 60, 175), ('amin', 75, 180), ('mahdi', 90, 190)]
Или эквивалентно:
employee_list = [('amin', 75, 180), ('mahdi', 90, 190), ('mamad', 75, 175), ('ahmad', 60, 175)]
employee_list.sort(key=lambda x: x[2])
print(employee_list)
# [('mamad', 75, 175), ('ahmad', 60, 175), ('amin', 75, 180), ('mahdi', 90, 190)]
Исправление вашего кода
Вы используете два вложенных for
цикла и никогда не выполняете повторную инициализацию max_weight
во время двух запусков внутреннего цикла. После первого запуска внутреннего цикла max_weight
содержит максимальное значение из начального списка; таким образом, последующие прогоны не могут его обновить, поскольку все остальные элементы списка имеют меньшее значение. Следовательно, ваш внутренний цикл продолжает пытаться получить pop
максимальный элемент из начального списка, вместо того, чтобы указывать max, затем второй по величине, затем третий по величине и т.д.
Просто переместите инициализацию max_weight
внутри внешнего цикла, непосредственно перед началом внутреннего цикла:
sorted_employee = []
i = len (employee_list)
for z in range (i):
max_weight = 0
max_weight_path = ''
for x in employee_list:
if x[2] > max_weight:
max_weight = x[2]
max_weight_path = x
elif x[2] == max_weight:
if x[1] < max_weight_path[1]:
max_weight_path = x
sorted_employee.append (max_weight_path)
employee_list.pop (employee_list.index (max_weight_path))
print(sorted_employee)
# [('mahdi', 90, 190), ('amin', 75, 180), ('ahmad', 60, 175), ('mamad', 75, 175)]
Общие принципы отладки
Интерпретатор сообщает вам ValueError: ('mahdi', 90, 190) is not in list
, что вы уверены, что ('mahdi', 90, 190)
оно должно быть в списке. Что произошло?
Первое, что вы можете сделать, это добавить print
оператор непосредственно перед pop
оператором, который вызвал исключение, чтобы распечатать значения всех переменных и понять, что происходит:
sorted_employee = []
max_weight = 0
max_weight_path = ''
i = len (employee_list)
for z in range (i):
for x in employee_list:
if x[2] > max_weight:
max_weight = x[2]
max_weight_path = x
elif x[2] == max_weight:
if x[1] < max_weight_path[1]:
max_weight_path = x
sorted_employee.append (max_weight_path)
print('DEBUG z={}:n max_weight_path={}n employee_list ={}n sorted_employee={}'.format(z, max_weight_path, employee_list, sorted_employee))
employee_list.pop (employee_list.index (max_weight_path))
Вывод:
DEBUG z=0:
max_weight_path=('mahdi', 90, 190)
employee_list =[('amin', 75, 180), ('mahdi', 90, 190), ('mamad', 75, 175), ('ahmad', 60, 175)]
sorted_employee=[('mahdi', 90, 190)]
('mahdi', 90, 190)
DEBUG z=1:
max_weight_path=('mahdi', 90, 190)
employee_list =[('amin', 75, 180), ('mamad', 75, 175), ('ahmad', 60, 175)]
sorted_employee=[('mahdi', 90, 190), ('mahdi', 90, 190)]
Traceback (most recent call last):
File "<stdin>", line 11, in <module>
ValueError: ('mahdi', 90, 190) is not in list
Таким образом, вы, вероятно, узнали бы, в чем проблема: мы продолжаем пытаться удалить 'mahdi'
из employee_list
и добавить его в sorted_employee
, что во второй раз завершается неудачей.
Ответ №2:
Я действительно не понимаю, что вы пытаетесь сделать в своем коде, но я бы сделал это именно так. Сначала сделайте копию, если вы хотите сохранить исходный порядок в отдельном списке. После используйте метод сортировки и используйте лямбда-функцию для ключа. Ключ — это значение, используемое для сортировки. x в лямбда-функции указывает на кортеж внутри списка. Поэтому он использует третий элемент кортежа (индекс 2) для сортировки.
Если вам не нужна копия, вы можете просто отсортировать исходный список. Если вы хотите выполнить сортировку по второму элементу (который, я полагаю, является весом), вам следует использовать x[1] .
employee_list = [('amin', 75, 180), ('mahdi', 90, 190), ('mamad', 75, 175), ('ahmad',
60, 175)]
sorted_employee = employee_list[:]
sorted_employee.sort(key=lambda x: x[2])
print(sorted_employee)
Комментарии:
1. Если вы собираетесь скопировать список, вы можете написать напрямую
sorted_employee = sorted(employee_list, key=lambda x: x[2])
.