Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 a list with objects

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

Every object object_i has an attribute key.

I want to sort the objects in object_list by the order of 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 must be a more pythonic way, then this brute force one. :-) How would you solve this?

like image 541
Aufwind Avatar asked Dec 28 '22 19:12

Aufwind


2 Answers

First, create a dictionary mapping object keys to objects:

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

Next create the sorted list using a list comprehension:

new_list = [d[key] for key in string_list]
like image 58
Sven Marnach Avatar answered Mar 08 '23 23:03

Sven Marnach


Map each key to its desired precedence:

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

Then sort by precedence:

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

To handle keys that might not 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 items), you can simplify:

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

However, this is prohibitive for larger lengths of string_list.

like image 42
Fred Nurk Avatar answered Mar 08 '23 23:03

Fred Nurk