mahmoud / glom

☄️ Python's nested data operator (and CLI), for all your declarative restructuring needs. Got data? Glom it! ☄️
https://glom.readthedocs.io
Other
1.89k stars 61 forks source link

How to access more than one field without creating a dict? #207

Open kurka opened 3 years ago

kurka commented 3 years ago

Say I have the following data structure:

target = [{'a': 1, 'b': 1}, {'a': 2, 'b': 2}]

I want to create a spec that access both fields 'a' and 'b' at the same level, but instead of storing their values on a dictionary, I want to store on a tuple, so to achieve:

glom(target, spec) == [(1, 1), (2, 2)]

For example:

I was able to obtain the desired result with:

spec = [({'a': 'a', 'b': 'b'}, lambda t: tuple(t.values())]

But I wonder if there is a more appropriate way? Thanks in advance!

mathrick commented 3 years ago

It depends somewhat on whether you want to access all fields, or named subset.

For all fields, the lambda t: tuple(t.values()) method is the most appropriate (it could also be rewritten as Invoke(tuple).specs(T.values())).

If you want to access a specific, static set of fields however, then you could use the new Fill mode:

glom(target, [Fill((T['a'], T['b']))])
# or
glom(target, [Fill((Path('a'), Path('b')))])

Although truth be told, the way Fill actually works is rather different from what I understood it to be from the docs. My understanding was that this would work for what you're trying to do, but it doesn't:

# not the expected result
glom(target, [Fill(('a', 'b'))])
>>> [('a', 'b'), ('a', 'b')]