2

I'm trying to pick a most common item among a list based on the element's attribute.

a1 = Myclass(name='a')
a2 = Myclass(name='a')
b1 = Myclass(name='b')
l = [a1,a2,b1]

if most_common(l, attr_name='name') in [a1, a2]:
   # I want this true 
   # 'a' is the most occured 'name'

Basically I want to modify the code https://stackoverflow.com/a/1520716/433570

key = operator.itemgetter(0) then operator.attrgetter(attr_name)

wonder if that's possible?

Community
  • 1
  • 1
eugene
  • 39,839
  • 68
  • 255
  • 489

2 Answers2

2

I stumbled on the question looking for the same thing. I don't like the accepted answer since it doesn't actually answer the question. Looked at Python's implementation of attrgetter and decided to write one.

https://docs.python.org/2/library/operator.html#operator.attrgetter

def resolve_itemattr(obj, attr):
    for name in attr.split("."):
        try:
            obj = obj[name]
        except TypeError:
            obj = getattr(obj, name)
    return obj


def itemattrgetter(attr):
    """
    Combo itemgetter and attrgetter
    """
    def g(obj):
        return resolve_itemattr(obj, attr)
    return g

It supports nested properties. I've stripped the handling of multiple attrs but it wouldn't be hard to put that back in.

This let's you use itemattrgetter to first try getting the item, failing that, get the attr.

dalore
  • 5,594
  • 1
  • 36
  • 38
0

You can preprocess your list:

attr_getter = operator.attrgetter('name')
names = map(attr_getter, l)
if most_common(names) in set(map(attr_getter, [a1, a2])):
    pass # do smth here
alko
  • 46,136
  • 12
  • 94
  • 102