Suppose I have two lists:
a = ['30', '10', '90', '1111', '17']
b = ['60', '1201', '30', '17', '900']
How would you sort this most efficiently, such that:
list b
is sorted with respect to a
. Unique elements in b
should be placed at the end of the sorted list. Unique elements in a
can be ignored.
example output:
c = ['30', '17', '60', '1201', '900']
Sorry, it's a simple question. My attempt is stuck at the point of taking the intersection.
intersection = sorted(set(a) & set(b), key = a.index)
There is no need to actually sort here. You want the elements in a
which are in b
, in the same order as they were in a
; followed by the elements in b
which are not in a
, in the same order as they were in b
.
We can just do this with two filters, using the sets for fast membership tests:
>>> a = ['30', '10', '90', '1111', '17']
>>> b = ['60', '1201', '30', '17', '900']
>>> a_set = set(a)
>>> b_set = set(b)
>>> [*filter(lambda x: x in b_set, a), *filter(lambda x: x not in a_set, b)]
['30', '17', '60', '1201', '900']
Or if you prefer comprehensions:
>>> [*(x for x in a if x in b_set), *(x for x in b if x not in a_set)]
['30', '17', '60', '1201', '900']
Both take linear time, which is better than sorting.
You can create a custom dictionary, with the keys being the entries in a
and the values their position. Then sort b
according to the values in the dictionary. You can use dict.get
for the lookup and inf
if the value is not present:
a = ['30', '10', '90', '1111', '17']
b = ['60', '1201', '30', '17', '900']
d = {i:ix for ix, i in enumerate(a)}
#{'30': 0, '10': 1, '90': 2, '1111': 3, '17': 4}
sorted(b, key=lambda x: d.get(x, float('inf')))
#['30', '17', '60', '1201', '900']
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