3

I have a list of objects look like below:

[{'id': 17L,
  'price': 0,
  'parent_count': 2},
 {'id': 39L,
  'price': 0,
  'parent_count': 1},
 {'id': 26L,
  'price': 2.0,
  'parent_count': 4},
 {'id': 25L,
  'price': 2.0,
  'parent_count': 3}]

I want to sort the objects by 'parent_count' in order to look like this:

 [{'id': 39L,
   'price': 0,
   'parent_count': 1},
  {'id': 17L,
   'price': 0,
   'parent_count': 2},
  {'id': 25L,
   'price': 2.0,
   'parent_count': 3},
  {'id': 26L,
   'price': 2.0,
   'parent_count': 4}]

Does anyone know a function?

2
  • 2
    Is 'parent_count' an optional key? The first object above has 'parent_say', not 'parent_count'? Commented Jul 27, 2012 at 10:22
  • i have edited the question. im sorry i wrote it wrong. there is no 'parent_say' key. Commented Jul 27, 2012 at 10:55

5 Answers 5

12

Use operator.itemgetter("parent_count") as key parameter to list.sort():

from operator import itemgetter
my_list.sort(key=itemgetter("parent_count"))
Sign up to request clarification or add additional context in comments.

6 Comments

This will raise a KeyError on the object that has 'parent_say' in place of 'parent_count'. If 'parent_count' is optional itemgetter() will need to be replaced with a callable that will return a suitable default value instead of raising KeyError.
@RobCowie: I will assume for now this was a typo – let's wait what the OP says.
@RobCowie It's a consistent typo if it is (being both in source and output data)
sorry man i wrote it wrong. all of them are 'parent_count'. there is no 'parent_say'.
@ErenSüleymanoğlu: As do all mutating methods in Python. It sorts the list in place.
|
3

Also, you can use this method:

a = [{'id': 17L, 'price': 0, 'parent_count': 2}, {'id': 18L, 'price': 3, 'parent_count': 1}, {'id': 39L, 'price': 1, 'parent_count': 4}]
sorted(a, key=lambda o: o['parent_count'])

Result:

[{'parent_count': 1, 'price': 3, 'id': 18L}, {'parent_count': 2, 'price': 0, 'id': 17L}, {'parent_count': 4, 'price': 1, 'id': 39L}]

Comments

1

Do you actually have "parent_say" and "parent_count"?

def get_parent(item):
    return item.get('parent_count', item['parent_say'])
    # return item.get('parent_count', item.get('parent_say')) if missing keys should just go to the front and not cause an exception

my_list.sort(key=get_parent)

or a bit more generic

def keygetter(obj, *keys, **kwargs):
    sentinel = object()
    default = kwargs.get('default', sentinel)
    for key in keys:
        value = obj.get(key, sentinel)
        if value is not sentinel:
            return value
    if default is not sentinel:
        return default
    raise KeyError('No matching key found and no default specified')

Comments

0
my_list.sort(key=lambda x:x["parent_count"])

Comments

0

You can also do:

my_list.sort(key=lambda x: x.get('parent_count'))

which doesn't require operator.itemgetter and doesn't cause an error if the key doesn't exist (those that don't have the key get put at the start).

1 Comment

@ErenSüleymanoğlu it is an in-place sort. if you want a sorted copy, use the sorted builtin with the same args (but with the list my_list as the first arg)

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.