开发者

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 obje开发者_开发技巧ct_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?


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]


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.


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 the in-place substitution:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜