The Oddler - 1 year ago 45

Python Question

I have two lists of equal length, one containing numbers, the other strings and

`None`

Before the second list could only contain string (so no

`None`

`weights, urls = zip(*sorted(zip(unordered_weights, unordered_urls), reverse=True))`

The numbers are in the "weights" array, the strings in the "urls" array. This worked fine.

However, now that I allow

`None`

`TypeError: unorderable types: str() < NoneType()`

For some reason it's also trying to sort the strings, I guess in case the weights are the same. How can I fix this?

I'm using Python 3, I read that in Python 2

`None`

Answer

Sorting tuples is done lexicographically - first the first elements are compared, if they are equal then the second, which in your case can be `None`

. You can sort using only the weights by extracting it as the sorting key through the `key`

argument to `sorted()`

:

```
weights, urls = zip(*sorted(zip(unordered_weights, unordered_urls), reverse=True, key=lambda x: x[0]))
```

Observe:

```
In [1]: unordered_urls = ['b', 'a', None, 'c', None]
In [2]: unordered_weights = [1, 0, 0, 5, 2] # the 'a' and None have the same weight
In [3]: weights, urls = zip(*sorted(zip(unordered_weights, unordered_urls), reverse=True))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-61fb3631580a> in <module>()
----> 1 weights, urls = zip(*sorted(zip(unordered_weights, unordered_urls), reverse=True))
TypeError: unorderable types: str() < NoneType()
In [4]: weights, urls = zip(*sorted(zip(unordered_weights, unordered_urls), reverse=True, key=lambda x: x[0]))
In [5]: weights
Out[5]: (5, 2, 1, 0, 0)
In [6]: urls
Out[6]: ('c', None, 'b', 'a', None)
```

Source (Stackoverflow)