3

Is there a recursive itemgetter in python. Let's say you have an object like

d = {'a': (1,2,3), 'b': {1: (5,6)}}

and I wanted to get the first element of the tuple from d['a']? As far as I can tell itemgetter will only do one level, i.e. get me a or b or both.

Is there some clever way of combining itertools with itemgetter to produce the desired result.

So basically what I want to be able to call is

from operator import itemgetter
d = {'a': (1,2), 'b': (4, (5,))}
itemgetter({'a': 0})(d) --> 1
itemgetter({'b': 0})(d) --> 4
itemgetter({'b': {1: 0}})(d) --> 5

d = {'a': {'b': (1,2,3)}}
itemgetter({'a': {'b': 2}})(d) --> 3
Matti Lyra
  • 12,828
  • 8
  • 49
  • 67
  • ok, so there is this (https://pypi.python.org/pypi/jmespath) which does what I want, but is not part of the standard library – Matti Lyra Oct 26 '16 at 09:31
  • I don't know if it is clever or not, but `a1 = lambda d: itemgetter(1)(itemgetter('a')(d))` will do as requested, i.e. `a1(d)` will "get the first element of the tuple from `d['a']`". – AXO Jun 28 '20 at 09:01

1 Answers1

10

I don't like 'clever' ways. Obvious is better.

You can very easily write a getter that iterates along a list of subscripts:

def getter(x, *args):
    for k in args:
        x = x[k]
    return x

>>> d = {'a': (1,2,3), 'b': {1: (5,6)}}
>>> getter(d, 'a', 0)
1
wim
  • 338,267
  • 99
  • 616
  • 750
nigel222
  • 7,582
  • 1
  • 14
  • 22
  • 1
    Explicit is better than implicit... except when it isn't. It's all full of... well, it's basically tradeoffs all the way down. And yes, you can write that yourself. But you can do so for tons of the syntactic sugar in core Python. Decorators? – Jürgen A. Erhard Feb 21 '17 at 05:41