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