On Sun, Feb 23, 2020 at 10:17:03PM -0000, Alex Hall wrote:
Steven D'Aprano wrote:
Conceptually, we should be able to reason that every object that supports indexing should be iterable, without adding a special case exception "...except for str".
Strings already have an exception in this area. Usually `x in y` means `any(x == elem for elem in y)`.
I don't think that there is anything specific to the `in` operator that demands that it is implemented that way. It is certainly a reasonable default implementation (I think Ruby offers it as method on a base class) but the `in` operator conceptually provides a containment test which might be far more general than the above: - number in interval - location in region - subset in set - subtree in tree - offence in criminal_record - monster in room just off the top of my head. In the case of strings, if the argument is a length-1 string, then your implementation works. If it isn't, a generalisation of it works: rather than iterate over substrings of length 1, iterate over substrings of the same length as the argument. So conceptually we have the string `in` operator being equivalent to: any(arg == sub for sub in thestring) except that iteration is not necessarily in length-1 chunks. (Note that for efficiency reasons, string containment testing may not actually be implemented in that way.)
Another somewhat related example: we usually accept that basically every object can be treated as a boolean, even more so of it has a `__len__`. But numpy and pandas break this 'rule' by raising an exception if you try to treat an array as a boolean
Yes, they do, and I think they are wrong to have done so. But they had their reasons, and its hard to know whether any other alternative would have been better. -- Steven