I need to sort a list based on the order of the elements in another list which is shorter ie, doesn't have all the elements compared to the list I'm sorting. I run into this error when using the sort(key=short_list)
:
long_list = ['y', 'z', 'x', 'c', 'a', 'b']
short_list = ['b', 'c', 'a']
long_list.sort(key=short_list.index)
ValueError: 'x' is not in list
Is there another way to sort the long_list
to result in a list
that maintains the order of short_list
followed by the order of the elements in the long_list
?
['b', 'c', 'a', 'y', 'z', 'x']
Approach : Zip the two lists. Create a new, sorted list based on the zip using sorted(). Using a list comprehension extract the first elements of each pair from the sorted, zipped list.
sort() is one of Python's list methods for sorting and changing a list. It sorts list elements in either ascending or descending order. sort() accepts two optional parameters. reverse is the first optional parameter.
There will be three distinct ways to sort the nested lists. The first is to use Bubble Sort, the second is to use the sort() method, and the third is to use the sorted() method.
Something like this should work:
def position(value):
try:
return short_list.index(value)
except ValueError:
return len(short_list)
long_list.sort(key=position)
Sorting is guaranteed to be stable, so using len(short_list)
ensures that the unknown values sort last.
You can use in
to detect if the element is in the short_list and a ternary to return a tuple based on that.:
>>> long_list = ['y', 'z', 'x', 'c', 'a', 'b']
>>> short_list = ['b', 'c', 'a']
>>> sorted(long_list, key=lambda e: (short_list.index(e),e) if e in short_list else (len(short_list),e))
['b', 'c', 'a', 'x', 'y', 'z']
Since Python sorts are stable, the order will only change based on a change of the elements themselves. To make that change, we can use a tuple with either a (index_of_the_element, element)
of (len(short_list), element)
to effect that change.
If you want the elements to not change order if the element is not in short list, just return an empty tuple:
>>> sorted(long_list, key=lambda e: (short_list.index(e),e) if e in short_list else (len(short_list),))
['b', 'c', 'a', 'y', 'z', 'x']
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