4

In short: How can I slice in glom? That is, being able to specify that I want to extract from several indices (e.g. y = x[(2, 5, 11)]), not just a single one (e.g. y = x[2]).

Simple example: Say I have this data:

d = {'_result': [[1, 'a'], [2, 'b'], [3, 'c']]}

To extract a named zip(*) of the "_result" list of lists, I could do this:

from glom import Spec
extract = Spec(('_result', 
                  lambda x: list(zip(*x)), 
                  lambda x: {'x': x[0], 'y': x[1]})).glom

And I'd get what I want:

>>> extract(d)
{'x': (1, 2, 3), 'y': ('a', 'b', 'c')}

But I'd like to be able to do something like...

extract = Spec(('_result', {'x': '*.0', 'y': '*.1'})).glom

or

extract = Spec(('_result', {'x': '[:].0', 'y': '[:].1'})).glom

An even more advanced wish...

I could imagine such syntactic sugar as being able to specify paths like

"a.[2:3, -5:].{'foo', 'bar'}.name"

could come in handy. Even (and possibly safer) if it were by an explicit glom.Path definition, such as

from glom import Path
path = Path('a', 
            ((slice(2, 3, None), slice(-5, None, None)),), 
            {'foo', 'bar'},
            'name')

Where in my (probably not best choice) mini-language, the {'foo', 'bar'} means we're extracting the values for both of those keys.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
thorwhalen
  • 1,920
  • 14
  • 26

1 Answers1

2
>>> d = [[1, 'a'], [2, 'b'], [3, 'c']]
>>> glom(d, {'x': [T[0]], 'y': [T[1]]})
{'x': [1, 2, 3], 'y': ['a', 'b', 'c']}

glom co-creator here :-)

T has got you covered. Strings are parsed and converted into Path instances. Paths are convenient and Ts are precise.

If you want to mix them together, you can either join them with a tuple or use the explicit Path constructor.

>>> Path('a.b', T[1:3])
Path('a.b', T[slice(1, 3, None)])
Kurt Rose
  • 36
  • 3