2
\$\begingroup\$

I have a list of orders (each order is a dict) which looks like this (simplified version) :

[{'name' : XXX,
  'id' : { 'order_id_local' : 'xxx_001'}},
 {'name' : XXX,
  'id' : { 'order_id_local' : 'xxx_002'}},
 {'name' : XXX,
  'id' : {}},
 {'name' : XXX,
  'id' : { 'order_id_local' : 'xxx_002'}},
 {'name' : XXX,
  'id' : { 'order_id_local' : 'xxx_003'}},
  ...]

As you can see there could be duplicate for the key 'order_id_local' but also nothing. What I would like to do is to get the last distinct 3 'order_id_local' in a list, beginning from the last one. Here it will be ['xxx_0003', 'xxx_002', 'xxx_001'].

What i did is :

 id_orders = [x['id']['order_id_local'] for x in order_list if 'order_id_local' in x['id']]  
 id_orders = [x for x in id_orders if x is not None]
 id_orders = list(reversed(sorted(set(id_orders))[-3:]))

It works but when i see this id_orders three times and those nested functions, i'm wondering if there is no a more efficient and pythonic way to do this.

\$\endgroup\$
  • \$\begingroup\$ How large is your actual order_list ? \$\endgroup\$ – RomanPerekhrest Jan 21 at 7:38
  • \$\begingroup\$ around an hundred orders per name, and i get the list for each name \$\endgroup\$ – TmSmth Jan 21 at 22:44
2
\$\begingroup\$

Use a dict comprehension to keep track of the last index for each order_id_local and skip blank entries:

local_ids = {order['id']['order_id_local']:n for n,order in enumerate(data) if order['id']}

Then reverse sort the dictionary keys by their value and slice off the first 3:

sorted(local_ids.keys(), reverse=True, key=local_ids.get)[:3]

result:

['xxx_003', 'xxx_002', 'xxx_001']
\$\endgroup\$
  • \$\begingroup\$ That's what i was looking for, thanks ! \$\endgroup\$ – TmSmth Jan 21 at 22:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.