У меня есть список кортежей, который выглядит примерно так:
[('abc', 121),('abc', 231),('abc', 148), ('abc',221)]
Я хочу отсортировать этот список в порядке возрастания на целое значение внутри кортежей. Возможно ли это?
У меня есть список кортежей, который выглядит примерно так:
[('abc', 121),('abc', 231),('abc', 148), ('abc',221)]
Я хочу отсортировать этот список в порядке возрастания на целое значение внутри кортежей. Возможно ли это?
Попробуйте использовать ключевое слово key
с sorted()
.
sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)], key=lambda x: x[1])
key
должна быть функцией, которая идентифицирует, как извлечь сопоставимый элемент из вашей структуры данных. В вашем случае это второй элемент кортежа, поэтому мы получаем доступ к [1]
.
Для оптимизации см. ответ jamylak с помощью itemgetter(1)
, который по существу является более быстрой версией lambda x: x[1]
.
>>> from operator import itemgetter
>>> data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)]
>>> sorted(data,key=itemgetter(1))
[('abc', 121), ('abc', 148), ('abc', 221), ('abc', 231)]
IMO с использованием itemgetter
более читабельна в этом случае, чем решение @cheeken. это
также быстрее, поскольку почти все вычисления будут выполняться на стороне c
(без каламбура), а не при использовании 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
Как неофит python, я просто хотел упомянуть, что если бы данные действительно выглядели следующим образом:
data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)]
то sorted()
будет автоматически сортироваться по второму элементу в кортеже, так как первые элементы идентичны.
Добавляя к ответу Cheeken, Так вы сортируете список кортежей по 2-му элементу в порядке убывания.
sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)],key=lambda x: x[1], reverse=True)
Из вики файла python:
>>> from operator import itemgetter, attrgetter
>>> sorted(student_tuples, key=itemgetter(2))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
>>> sorted(student_objects, key=attrgetter('age'))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
Для метода лямбда-избегания сначала определите свою собственную функцию:
def MyFn(a):
return a[1]
то
sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)], key=MyFn)
Для Python 2.7+
это работает, что делает принятый ответ несколько более читаемым:
sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)], key=lambda (k, val): val)
Для размещения на месте используйте
foo = [(list of tuples)]
foo.sort(key=lambda x:x[0]) #To sort by first element of the tuple
Тот факт, что значения сортировки в OP являются целыми числами, не имеет отношения к самому вопросу. Другими словами, принятый ответ будет работать, если значением сортировки является текст. Я привожу это также, чтобы указать, что сортировка может быть изменена во время сортировки (например, для учета верхнего и нижнего регистра).
>>> sorted([(121, 'abc'), (231, 'def'), (148, 'ABC'), (221, 'DEF')], key=lambda x: x[1])
[(148, 'ABC'), (221, 'DEF'), (121, 'abc'), (231, 'def')]
>>> sorted([(121, 'abc'), (231, 'def'), (148, 'ABC'), (221, 'DEF')], key=lambda x: str.lower(x[1]))
[(121, 'abc'), (148, 'ABC'), (231, 'def'), (221, 'DEF')]