1

This works, according to the documentation:

>>> inventory = [('apple', 3), ('banana', 2), ('pear', 5), ('orange', 1)]
>>> list(map(operator.itemgetter(1), inventory))
[3, 2, 5, 1]

Now I want to do something similar, for a list of dicts:

>>> data = [{'xxx': 'x'}, {'xxx': 'y'}]
>>> list(map(operator.attrgetter('xxx'), data))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'xxx'

I was expecting:

['x', 'y']

But it seems attrgetter does not work for dictionaries (only for classes?). How can I setup an "element getter" for dictionaries?

blueFast
  • 41,341
  • 63
  • 198
  • 344

2 Answers2

2

Well, the item you want to get is 'xxx'. (In both cases, you want to call the object's __getitem__ method for each object in the list.)

>>> from operator import itemgetter
>>> data = [{'xxx': 'x'}, {'xxx': 'y'}]
>>> map(itemgetter('xxx'), data)
['x', 'y']

Think of attributes as anything you access via the dot notation, i.e. mydict.xxx in your case. You should see why that fails.

timgeb
  • 76,762
  • 20
  • 123
  • 145
  • Strange that the documentation for itemgetter only shows examples for access of list or tuples elements, that is, for integer indexes – blueFast May 01 '17 at 09:22
2

As mentioned in timgeb's answer, you should be calling itemgetter with the key (because attrgetter are used to get the class attribute which are accessible by . like class_obj.<attribute>).

In order to achieve your desired result, usage of list comprehension is a easier approach:

>>> data = [{'xxx': 'x'}, {'xxx': 'y'}]
>>> [d['xxx'] for d in data]
['x', 'y']

Also, please note that map since python 3.x returns a generator object instead of a list object.

Community
  • 1
  • 1
Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126