I have a dict of lists like this:
a = [
{'p': 3, 'id': 'ab1'},
{'p': 10, 'id': 'ab2'},
{'p': 5, 'id': 'ab3'},
{'p': 8, 'id': 'ab4'},
{'id': 'ab5'}
]
I want to sort a
by the value of p
. If dict doesn't has p
, put it behind. I tried this way:
print sorted(a, key=lambda i: i.get('p'))
and got result:
[{'id': 'ab5'}, {'p': 3, 'id': 'ab1'}, {'p': 5, 'id': 'ab3'}, {'p': 8, 'id': 'ab4'}, {'p': 10, 'id': 'ab2'}]
but want to get is:
[{'p': 3, 'id': 'ab1'}, {'p': 5, 'id': 'ab3'}, {'p': 8, 'id': 'ab4'}, {'p': 10, 'id': 'ab2'},{'id': 'ab5'}]
What can I do to get the correct result with easier way?
For python2 and python3 both, you can do as follows, where I assume if the value of p
is missing, I am assuming sys.maxsize
value, which will ensure that if we have missing values for p
, they are always at the end of the list
import sys
a = [
{'p': 3, 'id': 'ab1'},
{'p': 10, 'id': 'ab2'},
{'p': 5, 'id': 'ab3'},
{'p': 8, 'id': 'ab4'},
{'id': 'ab5'}
]
print(sorted(a, key=lambda i: i.get('p', sys.maxsize)))
Which will give you
[{'p': 3, 'id': 'ab1'}, {'p': 5, 'id': 'ab3'}, {'p': 8, 'id': 'ab4'}, {'p': 10, 'id': 'ab2'}, {'id': 'ab5'}]
Another solution if comparing to sys.maxsize
is overkill, is to separate out the dictionaries without the key p
, sort the remaining dictionary which contain the key p
, and then extend it by attaching the non p
key dictionaries like so. This also avoids us from providing a default value for p
in item.get()
import sys
a = [
{'p': 3, 'id': 'ab1'},
{'p': 10, 'id': 'ab2'},
{'p': 5, 'id': 'ab3'},
{'p': 8, 'id': 'ab4'},
{'id': 'ab5'}
]
#Dictionaries with key p
p_items = [item for item in a if 'p' in item.keys()]
#Dictionaries not with key p
non_p_items = [item for item in a if 'p' not in item.keys()]
#Sort the p-key dictionaries
result = sorted(p_items, key=lambda i: i.get('p'))
#Attach non p-key dictionay items at end
result.extend(non_p_items)
print(result)
Use
a = [
{'p': 3, 'id': 'ab1'},
{'p': 10, 'id': 'ab2'},
{'p': 5, 'id': 'ab3'},
{'p': 8, 'id': 'ab4'},
{'id': 'ab5'}
]
print(sorted(a, key=lambda i: i.get('p', "NA"))) #Setting a string as a default value.
#python 3 --> https://stackoverflow.com/questions/49829732/sorting-a-mixed-list-of-ints-and-strings
print(sorted(a, key=lambda v: (isinstance(v.get('p', "NA"), str), v.get('p', "NA"))))
Output:
[{'p': 3, 'id': 'ab1'}, {'p': 5, 'id': 'ab3'}, {'p': 8, 'id': 'ab4'}, {'p': 10, 'id': 'ab2'}, {'id': 'ab5'}]
Here's an option that I prefer that doesn't use lambda
:
import sys
from operator import methodcaller
a = [
{'p': 3, 'id': 'ab1'},
{'p': 10, 'id': 'ab2'},
{'p': 5, 'id': 'ab3'},
{'p': 8, 'id': 'ab4'},
{'id': 'ab5'}
]
print(sorted(a, key=methodcaller('get', 'p', sys.maxsize)))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.