How to sort a list/tuple of lists/tuples by the element at a given index?
sorted_by_second = sorted(data, key=lambda tup: tup[1])
or:
data.sort(key=lambda tup: tup[1]) # sorts in place
The default sort mode is ascending. To sort in descending order use the option reverse=True
:
sorted_by_second = sorted(data, key=lambda tup: tup[1], reverse=True)
or:
data.sort(key=lambda tup: tup[1], reverse=True) # sorts in place
Sort a list of tuples by 2nd item (integer value)
Try using the key
keyword with sorted()
.
sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)],
key=lambda x: x[1])
key
should be a function that identifies how to retrieve the comparable element from your data structure. In your case, it is the second element of the tuple, so we access [1]
.
For optimization, see jamylak's response using itemgetter(1)
, which is essentially a faster version of lambda x: x[1]
.
How to sort a list of tuples, by the second tuple element?
You can use sorted
method with a lambda function as below.
lst=[('TIPE_ORG', 'Corea'), ('TIPE_ORG', 'United Kingdom'), ('TIPE_ORG', 'Russia'), ('TIPE_ORG', 'Germany'),('TIPE_PER', 'Pepe Martínez')]
sorted(lst,key=lambda key:len((key[1])),reverse=True)
Output will be
[('TIPE_ORG', 'United Kingdom'),
('TIPE_PER', 'Pepe Martínez'),
('TIPE_ORG', 'Germany'),
('TIPE_ORG', 'Russia'),
('TIPE_ORG', 'Corea')]
Sort list of lists with tuples by first value
Your second attempt is close, you just need to sort each sublist.
for chunk in distancechunks:
chunk.sort(key=lambda x: x[0])
I'm not sure why you're trying to convert to int when you already have floats.
How to sort a tuple list in python
a = [("label 1", 5), ("label 2", 1), ("label 3", 3), ("label 4", 6)]
a = sorted(a, key = lambda x: int(x[1]), reverse = True)
a becomes
[('label 4', 6), ('label 1', 5), ('label 3', 3), ('label 2', 1)]
Sort tuple list with another list
Algorithm
You can distribute the tuples in a dict of lists according to the second element and iterate over order
indices to get the sorted list:
from collections import defaultdict
to_order = [(0, 1), (1, 3), (2, 2), (3, 2)]
order = [2, 1, 3]
bins = defaultdict(list)
for pair in to_order:
bins[pair[1]].append(pair)
print(bins)
# defaultdict(<class 'list'>, {1: [(0, 1)], 3: [(1, 3)], 2: [(2, 2), (3, 2)]})
print([pair for i in order for pair in bins[i]])
# [(2, 2), (3, 2), (0, 1), (1, 3)]
sort
or index
aren't needed and the output is stable.
This algorithm is similar to the mapping
mentioned in the supposed duplicate. This linked answer only works if to_order
and order
have the same lengths, which isn't the case in OP's question.
Performance
This algorithm iterates twice over each element of to_order
. The complexity is O(n)
. @alfasin's first algorithm is much slower (O(n * m * log n)
), but his second one is also O(n)
.
Here's a list with 10000 random pairs between 0
and 1000
. We extract the unique second elements and shuffle them in order to define order
:
from random import randrange, shuffle
from collections import defaultdict
from timeit import timeit
from itertools import chain
N = 1000
to_order = [(randrange(N), randrange(N)) for _ in range(10*N)]
order = list(set(pair[1] for pair in to_order))
shuffle(order)
def eric(to_order, order):
bins = defaultdict(list)
for pair in to_order:
bins[pair[1]].append(pair)
return list(chain.from_iterable(bins[i] for i in order))
def alfasin1(to_order, order):
arr = [[] for i in range(len(order))]
d = {k:v for v, k in enumerate(order)}
for item in to_order:
arr[d[item[1]]].append(item)
return [item for sublist in arr for item in sublist]
def alfasin2(to_order, order):
return sorted(to_order, key=lambda item: order.index(item[1]))
print(eric(to_order, order) == alfasin1(to_order, order))
# True
print(eric(to_order, order) == alfasin2(to_order, order))
# True
print("eric", timeit("eric(to_order, order)", globals=globals(), number=100))
# eric 0.3117517130003762
print("alfasin1", timeit("alfasin1(to_order, order)", globals=globals(), number=100))
# alfasin1 0.36100843100030033
print("alfasin2", timeit("alfasin2(to_order, order)", globals=globals(), number=100))
# alfasin2 15.031453827000405
Related Topics
Two Versions of Python on Linux. How to Make 2.7 the Default
Using Pip3: Module "Importlib._Bootstrap" Has No Attribute "Sourcefileloader"
Python Spawn Off a Child Subprocess, Detach, and Exit
Get Total Physical Memory in Python
In Python Script, How to Set Pythonpath
Python Subprocess.Popen "Oserror: [Errno 12] Cannot Allocate Memory"
How to Set Your Pythonpath in an Already-Created Virtualenv
Process List on Linux Via Python
Python-Dev Installation Error: Importerror: No Module Named Apt_Pkg
Cannot Kill Python Script With Ctrl-C
How to Update a Python Package
Django [Errno 13] Permission Denied: '/Var/Www/Media/Animals/User_Uploads'