I've a zip
object and I want to sort it(based on a specific key).
I've already seen How do I sort a zipped list in Python? but the accepted answer does not work in python 3.6 anymore.
For example
In [6]: a = [3,9,2,24,1,6]
In [7]: b = ['a','b','c','d','e']
In [8]: c = zip(a,b)
In [9]: c
Out[9]: <zip at 0x108f59ac8>
In [11]: type(c)
Out[11]: zip
In [12]: c.sort()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-12-a21727fa8976> in <module>()
----> 1 c.sort()
AttributeError: 'zip' object has no attribute 'sort'
# Wanted this to be sorted by the first element
In [13]: for l,r in c: print(l,r)
3 a
9 b
2 c
24 d
1 e
In other words how do I make the zip iteration order conform to the sorting order. I'm aware that converting a zip to a list of tuples will allow me to fix this, but I want to retain the zipped object (as it used to be in the good old days of python2.7)
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.
The sort is stable – if two items have the same key, their order will be preserved in the sorted list. The original items do not have to be comparable because the ordering of the decorated tuples will be determined by at most the first two items.
Sort by multiple keysYou can specify multiple arguments for operator. itemgetter() , and if the values for the first key are equal, they will be compared and sorted by the value of the next key. Note that if the order of the arguments is different, the result is also different.
zip()
in Python 3 returns an iterator; the inputs are zipped as you request elements from it. Iterators are not sortable, no.
You can use the sorted()
function to 'draw out' the elements and return a sorted list from them:
sorted(zip(a, b))
You could also convert the zip()
object to a list by calling list()
on it, then sort that result in-place with the list.sort()
method, but that's then more work than just using the sorted()
function.
sorted()
takes the same keyword arguments as list.sort()
does, so you can still use the same key
function:
Demo:
>>> a = [3, 9, 2, 24, 1, 6]
>>> b = ['a', 'b', 'c', 'd', 'e']
>>> sorted(zip(a, b))
[(1, 'e'), (2, 'c'), (3, 'a'), (9, 'b'), (24, 'd')]
>>> sorted(zip(a, b), key=lambda x: x[1])
[(3, 'a'), (9, 'b'), (2, 'c'), (24, 'd'), (1, 'e')]
Also see What is the difference between `sorted(list)` vs `list.sort()` ? python
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(). It will let you write a sort function also, based on which the collection will be sorted.
Here, I am sorting it based on the values of y
in each (x,y)
pair. .
>>> a = [3,9,2,24,1,6]
>>> b = ['a','b','c','d','e']
>>> c = zip(a,b)
>>>
>>> sorted(c, key = lambda x:x[1])
[(3, 'a'), (9, 'b'), (2, 'c'), (24, 'd'), (1, 'e')]
Note that, sorted
will return a new sorted list, whereas sort
will sort the collection in place.
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