That seems too esoteric to ever go into the language unfortunately. I love the idea of some sort of __in__ targeting values in mappings but have never been able to think of an elegant mechanism that uses the existing grammar sanely or introduces useful new grammar.
I've always thought that maps and a matching __maps__ would have been a nicer way of referring to the keys of a mapping with in/__in__ referring to the values. Although the semantics are a bit odd in that case. Technically the mapping maps a key, but the language semantic to to have it the other way around as in key is mapped by mapping.
foo = {'bar': 42}
assert 42 in foo
but which makes more sense below?
assert 42 maps foo
assert foo maps 42
or even
assert 42 mapped by foo
The benefits of including by in the grammar could be of consequence here too.
That's why none of the alternative solutions are attractive. They don't really improve on the existing semantics.
What bugs me is the implicitness of __in__ defaulting to keys for a mapping. We have .keys() and .values() which are nice and clear since they explicitly grab an object which has an unambiguous definition for __in__.
Double Edit: It's an implementation decision that had to be made and I'm not aware of the rationale or debate behind the original choice. It's directly attributable to the decision to make __iter__ return the keys for a mapping which is the root of my issue. It's presumably useful and convenient (from a language writer's perspective) for iteration of a mapping to be along the keys in whatever order they may be traversed but if that's all it comes down to, why should a mapping be iterable at all when there is obvious ambiguity in what may be iterated? Maybe there is some history I'm not aware of where the .keys(), .values() and .items() methods were introduced post-hoc and the previous behaviour was such due to their non-existence and the need to iterate and then index to get all values in the object.
I think I'm combining issues in a problematic way here and I don't even know what was going on when I typed __in__ (twice! :/) instead of __contains__ - I'll just blame the lack of coffee. I realise why the membership 'in' should operate on the hash table in memory for O(1) performance and it makes perfect sense. I've just never been fully comfortable with the idea that keys are considered the 'members' of a 'mapping' in and of themselves. Maybe because I usually consider one-way mapping as a special case.
The more reasonable (I think) problem I have is one of language semantics which is introduced by in being applicable to a mapping in the first place - why should a mapping be iterable at all if it is ambiguous (as I believe) as to what it should return? Members should be key:val pairs but membership checks refer only to keys and it's probably not unreasonable for a user to want any of .keys(), .values() or .items() when iterating. That's obviously why they're made available so why should __iter__ special case one of them?
I assume this is to match semantics introduced by the membership check and probably historical because without a .values() method, key iteration and lookups would be the usual way to get all values out of a mapping. This just seems like the kind of thing that could have been changed in Python3 (although 2to3 would probably not have been able to handle the syntax changes automatically).
> It's presumably useful and convenient (from a language writer's perspective) for iteration of a mapping to be along the keys in whatever order they may be traversed but if that's all it comes down to, why should a mapping be iterable at all when there is obvious ambiguity in what may be iterated?
Its iterable at all because early python didn't have generators, so iterating over dict.keys() would be inefficient for large dictionaries (since you would create an intermediate list just to iterate over.)
> Maybe there is some history I'm not aware of where the .keys(), .values() and .items() methods were introduced post-hoc and the previous behaviour was such due to their non-existence and the need to iterate and then index to get all values in the object.
Prior to Python 3.x, .keys(), .values(), and .items() returned lists (rather than generators providing a view on the underlying dict), which would generally be inefficient if the only purpose was to iterate over them once.
Well, nothing. Actually, I do not support Python having operators other than well-known, standard operators, like + - * / % and bitwise operators. My comment was just a quick and dirty idea which came to my mind after reading the parent comment of it.
I've always thought that maps and a matching __maps__ would have been a nicer way of referring to the keys of a mapping with in/__in__ referring to the values. Although the semantics are a bit odd in that case. Technically the mapping maps a key, but the language semantic to to have it the other way around as in key is mapped by mapping.
but which makes more sense below? or even The benefits of including by in the grammar could be of consequence here too.