Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting a heterogeneous list of objects in Python

Tags:

python

sorting

I have some custom objects and dictionaries that I want to sort. I want to sort both the objects the dictionaries together. I want to sort the objects by an attribute and the dictionaries by a key.

object.name = 'Jack'
d = {'name':'Jill'}

sort_me =[object, d]

How do I sort this list using the object's name attribute and the dictionary's 'name' key?

like image 376
hekevintran Avatar asked Oct 10 '09 20:10

hekevintran


People also ask

How do you sort a heterogeneous list in Python?

Method #2 : Using sorted() + key + lambda + isdigit() In this, we just sort the list using sorted() using key functionality using lambda function to segregate digits using isdigit().

Does Python allow heterogeneous lists?

Python lists are extremely simple to work with and are very flexible in nature. Python lists unlike arrays aren't very strict, Lists are heterogeneous which means you can store elements of different datatypes in them.

Can you sort a list of objects in Python?

Python lists have a built-in list. sort() method that modifies the list in-place. There is also a sorted() built-in function that builds a new sorted list from an iterable.

How do you sort a list of objects based on key in Python?

A simple solution is to use the list. sort() function to sort a collection of objects (using some attribute) in Python. This function sorts the list in-place and produces a stable sort. It accepts two optional keyword-only arguments: key and reverse.


1 Answers

What you are almost certainly looking for is to use the key= option for sorted(), which provides a function which returns an arbitrary sort key for each element. This function can check the type of its argument and take various actions. For instance:

import types

class obj(object):
    def __init__(self, arg):
        self.name = arg

def extract_name(obj):
    if type(obj) is types.DictType:
        return obj['name']
    else:
        return obj.__dict__['name']

d = { 'name': 'Jill'}    
print sorted([obj('Jack'), d], key=extract_name)

More information can be found on the Python wiki

RichieHindle's suggestion of using isinstance is a good one. And while I was at it I thought it might be nice to support arbitrary element names instead of hardcoding 'name':

def extract_elem_v2(elem_name):
    def key_extractor(obj):
        dct = obj if isinstance(obj, dict) else obj.__dict__
        return dct[elem_name]
    return key_extractor

Which you can use like so:

print sorted(list_of_stuff, key=extract_elem_v2('name'))
like image 166
Jack Lloyd Avatar answered Sep 19 '22 22:09

Jack Lloyd