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\$
2
  • \$\begingroup\$ How large is your actual order_list ? \$\endgroup\$ Commented Jan 21, 2020 at 7:38
  • \$\begingroup\$ around an hundred orders per name, and i get the list for each name \$\endgroup\$
    – TmSmth
    Commented Jan 21, 2020 at 22:44

1 Answer 1

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\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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