Сортировка списка кортежей по второму элементу (целое значение)
Я столкнулся с проблемой сортировки списка кортежей в Python. У меня есть список кортежей, который выглядит примерно так:
[('abc', 121), ('abc', 231), ('abc', 148), ('abc', 221)]
Мне нужно отсортировать этот список в порядке возрастания по целочисленному значению внутри кортежей. Направьте, пожалуйста, сможете ли вы помочь с этой задачей?
Заранее благодарю!
5 ответ(ов)
Попробуйте использовать аргумент key
функции sorted()
, который по умолчанию сортирует элементы в возрастающем порядке:
sorted(
[('abc', 121), ('abc', 231), ('abc', 148), ('abc', 221)],
key=lambda x: x[1]
)
Аргумент key
должен быть функцией, которая определяет, как извлекать сравнимый элемент из вашей структуры данных. В вашем случае это второй элемент кортежа, поэтому мы обращаемся к индексу [1]
.
Для оптимизации смотрите ответ jamylak, где используется operator.itemgetter(1)
, который является, по сути, более быстрым вариантом lambda x: x[1]
.
Ответ на ваш вопрос:
Да, использование itemgetter
в данном случае действительно более читаемо и, как показали замеры, также быстрее.
Вот пример использования itemgetter
для сортировки списка кортежей:
from operator import itemgetter
data = [('abc', 121), ('abc', 231), ('abc', 148), ('abc', 221)]
sorted_data = sorted(data, key=itemgetter(1))
print(sorted_data)
Результат будет следующим:
[('abc', 121), ('abc', 148), ('abc', 221), ('abc', 231)]
Как видно, sorted(data, key=itemgetter(1))
сортирует список по второму элементу каждого кортежа (то есть по числовым значениям).
Что касается производительности, результаты тестов показывают, что использование itemgetter
быстрее, чем использование lambda
для этой конкретной задачи. Вот результаты замеров:
>python -m timeit -s "from operator import itemgetter; data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)]" "sorted(data,key=itemgetter(1))"
1000000 loops, best of 3: 1.22 usec per loop
>python -m timeit -s "data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)]" "sorted(data,key=lambda x: x[1])"
1000000 loops, best of 3: 1.4 usec per loop
Как видно из этих замеров, использование itemgetter
(1.22 мкс на итерацию) быстрее, чем использование lambda
(1.4 мкс на итерацию). Таким образом, если вы ищете более быстрый и читаемый способ сортировки, itemgetter
— отличный выбор.
В дополнение к ответу Cheeken, вот как вы можете отсортировать список кортежей по второму элементу в убывающем порядке:
sorted([('abc', 121), ('abc', 231), ('abc', 148), ('abc', 221)], key=lambda x: x[1], reverse=True)
Используя параметр key
с функцией lambda
, мы указываем, что сортировка должна происходить по второму элементу кортежа (индекс 1). Параметр reverse=True
делает сортировку в убывающем порядке.
Если вы новичок в Python, стоит отметить, что если ваши данные действительно выглядят так:
data = [('abc', 121), ('abc', 231), ('abc', 148), ('abc', 221)]
то функция sorted()
автоматически отсортирует кортежи по второму элементу, так как все первые элементы идентичны. Таким образом, вы получите результат, отсортированный по вторым элементам кортежей.
Пример использования:
sorted_data = sorted(data)
print(sorted_data)
В результате вы получите:
[('abc', 121), ('abc', 148), ('abc', 221), ('abc', 231)]
Функция sorted()
сортирует кортежи, начиная с первого элемента, и если они равны, переходит ко второму элементу, что и происходит в вашем случае.
Для сортировки на месте используйте следующий код:
foo = [(список кортежей)]
foo.sort(key=lambda x: x[0]) # Для сортировки по первому элементу кортежа
Этот код выполняет сортировку списка foo
по первому элементу каждого кортежа с помощью метода sort()
, который изменяет исходный список.
В чем разница между списками и кортежами?
Как отсортировать список/кортеж списков/кортежей по элементу на заданном индексе
Список vs кортеж: когда использовать каждый?
Как получить последний элемент списка?
Как клонировать список, чтобы он не изменялся неожиданно после присваивания?