On 4/19/13 2:27 PM, Terry Jan Reedy wrote:
On 4/19/2013 10:27 AM, Matthew Gilson wrote:
) It seems to me that the operator module should have a `not_in` or
`not_contains` function.  It seems asymmetric that there exists a
`is_not` function which implements `x is not y` but there isn't a
function to represent `x not in y`.

There is also no operator.in.

True.  I'm not arguing that there should be ...
There is operator.contains and operator.__contains__.

Thankfully :-)

There is no operator.not_contains because there is no __not_contains__ special method. (Your point two, which I disagree with.)

But there's also no special method `__is_not__`, but there's a corresponding `is_not` in the operator module so I don't really see that argument. It's a matter of functionality that I'm thinking about in the first part.

     itertools.starmap(operator.not_in,x,y)

vs.

    itertools.starmap(lambda a,b: a not in b,x,y)

Pretty much every other operator in python (that I can think of) has an analogous function in the operator module.

2) I suspect this one might be a little more controversial, but it seems
to me that there should be a separate magic method bound to the `not in`
operator.

The reference manual disagrees.
"The operator not in is defined to have the inverse true value of in."

I would still leave that as the default behavior. It's by far the most useful and commonly expected. And I suppose if you *can't* have default behavior like that because that is a special case in itself, then that makes this second part of the request dead in the water at the outset (and I can live with that explanation).

 Currently, when inspecting the bytecode, it appears to me
that `not x in y` is translated to `x not in y` (this supports item 1
slightly).  However, I don't believe this should be the case. In
python, `x < y` does not imply `not x >= y` because a custom object can
do whatever it wants with `__ge__` and `__lt__` -- They don't have to
fit the normal mathematical definitions.

The reason for this is that the rich comparisons do not have to return boolean values, and do not for numarray arrays which, I believe, implement the operators itemwise.

Yes, you're correct about numpy arrays behaving that way. It can be very useful for indexing them.

It would also be fine for a special method `__not_contains__` to be expected to return a boolean value as well. It could still be very useful. Consider a finite square well from quantum mechanics. I could define `in` for my particle in the square well to return `True` if there is a 70% chance that it is located in the well (It's a wave-function, so it doesn't have a well defined position -- the particle could be anyway, but 7 out of 10 measurements will tell me it's in the well). It might be nice if I could define `not in` to be `True` if there is only a 30% chance that it is in the well. Of course, this leaves us with a no-man's land around the 50% mark. Is it in the well or not? There's no telling. I'm sure you could argue that this sort of thing *could* be done with rich comparisons, but I would consider that a deflection from the point at hand. It seems it should be up to the user to design the API most suited for their task. Or what about a `Fraternity` class. Are the new pledges in the fraternity or not? Maybe they should be considered neither in, nor out until pledge season is over.

> I don't see any reason why containment should behave differently.

'Design by analogy' is tricky because analogies often leave out important details. __contains__ *is* expected to return true/false.

" object.__contains__(self, item)
Called to implement membership test operators. Should return true if item is in self, false otherwise"

--
Terry Jan Reedy



--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to