What's the Pythonic way to sort a zipped list?
code :
names = list('datx')
vals = reversed(list(xrange(len(names))))
zipped = zip(names, vals)
print zipped
The code above prints [('d', 3), ('a', 2), ('t', 1), ('x', 0)]
I want to sort zipped by the values. So ideally it would end up looking like this [('x', 0), ('t', 1), ('a', 2), ('d', 3)].
You can't use sort on zip object, zip object doesn't have such attribute. But, you can convert the zip object to a list with list(zipped_object) and then apply sort on it, to do an in-place sort. But, as zipped object is also an iterable, my recommendation is to use sorted().
Python's zip() function is defined as zip(*iterables) . The function takes in iterables as arguments and returns an iterator. This iterator generates a series of tuples containing elements from each iterable. zip() can accept any type of iterable, such as files, lists, tuples, dictionaries, sets, and so on.
Python List sort() - Sorts Ascending or Descending List. The list. sort() method sorts the elements of a list in ascending or descending order using the default < comparisons operator between items. Use the key parameter to pass the function name to be used for comparison instead of the default < operator.
The zip() function combines the contents of two or more iterables. zip() returns a zip object. This is an iterator of tuples where all the values you have passed as arguments are stored as pairs. Python's zip() function takes an iterable—such as a list, tuple, set, or dictionary—as an argument.
Quite simple:
sorted(zipped, key=lambda x: x[1])
sorted(zipped, key = lambda t: t[1])
import operator
sorted(zipped, key=operator.itemgetter(1))
If you want it a little bit more faster, do ig = operator.itemgetter(1) and use ig as key function.
It's simpler and more efficient to zip them in order in the first place (if you can). Given your example it's pretty easy:
>>> names = 'datx'
>>> zip(reversed(names), xrange(len(names)))
<<< [('x', 0), ('t', 1), ('a', 2), ('d', 3)]
In your case you don't need to sort at all because you just want an enumerated reversed list of your names:
>>> list(enumerate(names[::-1])) # reverse by slicing
[(0, 'x'), (1, 't'), (2, 'a'), (3, 'd')]
>>> list(enumerate(reversed(names))) # but reversed is also possible
[(0, 'x'), (1, 't'), (2, 'a'), (3, 'd')]
But if you need to sort it then you should use sorted (as provided by @utdemir or @Ulrich Dangel) because it will work on Python2 (zip and itertools.zip) and Python3 (zip) and won't fail with an AttributeError like .sort(...) (which only works on Python2 zip because there zip returns a list):
>>> # Fails with Python 3's zip:
>>> zipped = zip(names, vals)
>>> zipped.sort(lambda x: x[1])
AttributeError: 'zip' object has no attribute 'sort'
>>> # Fails with Python 2's itertools izip:
>>> from itertools import izip
>>> zipped = izip(names, vals)
>>> zipped.sort(lambda x: x[1])
AttributeError: 'itertools.izip' object has no attribute 'sort'
But sorted does work in each case:
>>> zipped = izip(names, vals)
>>> sorted(zipped, key=lambda x: x[1])
[('x', 0), ('t', 1), ('a', 2), ('d', 3)]
>>> zipped = zip(names, vals) # python 3
>>> sorted(zipped, key=lambda x: x[1])
[('x', 0), ('t', 1), ('a', 2), ('d', 3)]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With