In python today, you can query a dictionary like so, d['some_key'] but you can only query one key at a time. If you attempt to query the dictionary using d[['key_a','key_b']] it returns with TypeError: unhashable type: 'list'
I propose that we add in so d[['key_a','key_b']] works the same way {key:value for key,value in d.items() if key in ['key_a','key_b']} works now, allowing users to quickly get multiple keys from a dictionary.
I believe this is an intuitive way to query multiple keys, it matches the behavior in Pandas DataFrames for querying multiple columns, so many python users already think in this way, making me think it is a natural way to do this operation with less typing than a dictionary comprehension.
Could you please clarify the following: the comprehension {key:value for key,value in d.items() if key in ['key_a','key_b']} creates a new dict (in an ineffective way, but let’s stay focused). Is this what you mean by “quering multiple keys”?
I don’t like this. I frequently use dictionaries with tuple keys, a legitimate and useful construct in Python today. Having easily confused syntax (just a typo away!) that provides completely different semantics sounds very frustrating.
Sure, you may not be mixing key types like this in a single dict, but it’s going to be very easy to use the wrong access syntax and get confusing errors.
I would prefer to use a slice with a tuple step to get a sub-dict from a dict. Something like:
In [371]: class SubDict(dict):
...: def __getitem__(self, what):
...: if not isinstance(what, slice):
...: return super().__getitem__(what)
...: if what.start is not None or what.stop is not None:
...: raise ValueError('SubDict slices must not have start or stop')
...: return type(self)(filter(lambda i: i[0] in what.step, self.items()))
...:
In [372]: d = SubDict({'a': 1, 'b': 2, 'c': 3})
In [373]: d[::('a', 'b')]
Out[373]: {'a': 1, 'b': 2}
def get_multiple(mapping, keys):
# Make keys a set for quicker membership checks
keyset = set(keys)
return {k: v for k, v in mapping.items() if k in keyset}
I don’t think this is a common enough need to justify built in syntax. But writing a helper in your project is easy, so the lack of built in syntax isn’t a major issue.
Personally, I’d prefer to return a list of values, rather than a sub-dictionary, which is another reason why picking one behaviour to “bless” as having built in syntax is questionable, but that’s a separate matter.