1

Im currently uniquifying a list of objects based on their name attribute by creating a dict of objects with the name value as the dict key like this:

obj_dict = dict()

for obj in obj_list:
    if not obj.name in obj_dict:
        obj_dict[obj.name] = obj

new_obj_list = obj_dict.items()

And I was wondering if there was a quicker or more pythonic way to do this.

4

3 回答 3

12

If two objects with the same name should always considered identical you could implement __eq__ and __hash__ accordingly. Then your solution would be as easy as storing all your objects in a set():

new_obj_list = list(set(obj_list))

Converting the list back to a set is probably not even necessary since the order is lost anyway so unless you need to do something with it that only works with a list but not with a set just keep using the set.

于 2012-08-11T12:58:43.563 回答
1

And if you need ordering:

oset = set()
new_obj_list = []
for o in obj_list:
    if o not in oset:
        oset.add(o)
        new_obj_list.append(o)
于 2012-08-11T13:16:16.460 回答
0

I would also go the set approach but then figured you want to be able to look-up by name I guess..., but here's another approach that doesn't require amending the class... (albeit a bit more expensive)... Note that you could add further sort parameters to sorted to order by other priorities (such as age, or gender etc...)

from operator import attrgetter
from itetools import groupby
unique_by_name = {key: next(item) for key, item in groupby(attrgetter('name'), sorted(obj_list, key=attrgetter('name')))}

There's a unique last seen recipe in itertools too.

Otherwise for different ordering requirements, put them as different class methods, (or one called 'sort' that takes a known order and calls an internal function)...

于 2012-08-11T13:22:05.287 回答