5

Сортировка списка кортежей по второму элементу (целое значение)

12

Я столкнулся с проблемой сортировки списка кортежей в Python. У меня есть список кортежей, который выглядит примерно так:

[('abc', 121), ('abc', 231), ('abc', 148), ('abc', 221)]

Мне нужно отсортировать этот список в порядке возрастания по целочисленному значению внутри кортежей. Направьте, пожалуйста, сможете ли вы помочь с этой задачей?

Заранее благодарю!

5 ответ(ов)

8

Попробуйте использовать аргумент 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].

2

Ответ на ваш вопрос:

Да, использование 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 — отличный выбор.

0

В дополнение к ответу Cheeken, вот как вы можете отсортировать список кортежей по второму элементу в убывающем порядке:

sorted([('abc', 121), ('abc', 231), ('abc', 148), ('abc', 221)], key=lambda x: x[1], reverse=True)

Используя параметр key с функцией lambda, мы указываем, что сортировка должна происходить по второму элементу кортежа (индекс 1). Параметр reverse=True делает сортировку в убывающем порядке.

0

Если вы новичок в 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() сортирует кортежи, начиная с первого элемента, и если они равны, переходит ко второму элементу, что и происходит в вашем случае.

0

Для сортировки на месте используйте следующий код:

foo = [(список кортежей)]
foo.sort(key=lambda x: x[0])  # Для сортировки по первому элементу кортежа

Этот код выполняет сортировку списка foo по первому элементу каждого кортежа с помощью метода sort(), который изменяет исходный список.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь