Given two lists in python, one with strings and one with objects, how do you map them?

I have a list of strings

string_list = ["key_val_1", "key_val_2", "key_val_3", "key_val_4", ...] 

and list with objects

 object_list = [object_1, object_2, object_3,...] 

Each object_i object has a key attribute.

I want to sort objects in object_list order string_list .

I could do something like

 new_list = [] for key in string_list: for object in object_list: if object.key == key: new_list.append(object) 

but there has to be a more pythonic path, then this brute force. :-) How would you solve this?

+4
source share
3 answers

First, create the keys for the objects matching the dictionary to the objects:

 d = dict((x.key, x) for x in object_list) 

Next, create a sorted list using list comprehension:

 new_list = [d[key] for key in string_list] 
+8
source

Match each key with the desired priority:

 key_precedence = dict((x, n) for n, x in enumerate(string_list)) 

Then sort by priority:

 object_list.sort(key=lambda x: key_precedence[x.key]) 

To handle keys that cannot be in string_list:

 default = -1 # put "unknown" in front default = sys.maxint # put "unknown" in back object_list.sort(key=lambda x: key_precedence.get(x.key, default)) 

If string_list is short (e.g. 10 or fewer elements), you can simplify:

 object_list.sort(key=lambda x: string_list.index(x.key)) # But it more cumbersome to handle defaults this way. 

However, this is too important for large string_list strings.

+2
source

You can use the cmp argument of the sort () method:

 object_list.sort(cmp=lambda x,y: cmp(string_list.index(x.key), string_list.index(y.key))) 

or use sorted () to avoid in-place replacements:

 sorted(object_list, cmp=lambda x,y: cmp(string_list.index(x.key), string_list.index(y.key))) 
0
source

All Articles