Feature Request: `operator.not_in`

2013-04-19 Thread Matthew Gilson
I believe that I read somewhere that this is the place to start 
discussions on feature requests, etc.  Please let me know if this isn't 
the appropriate venue (and what the appropriate venue would be if you know).


This request has 2 related parts, but I think they can be considered 
seperately:


1) 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`.


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.  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.  I don't see any reason why 
containment should behave differently.  `x in y` shouldn't necessarily 
imply `not x not in y`.  I'm not sure if `object` could have a default 
`__not_contains__` method (or whatever name seems most appropriate) 
implemented equivalently to:


 def __not_contains__(self,other):
  return not self.__contains__(other)

If not, it could probably be provided by something like 
`functools.total_ordering`.  Anyway, it's food for thought and I'm 
interested to see if anyone else feels the same way that I do.


Thanks,
~Matt
--
http://mail.python.org/mailman/listinfo/python-list


Re: Feature Request: `operator.not_in`

2013-04-19 Thread Terry Jan Reedy

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.
There is operator.contains and operator.__contains__.
There is no operator.not_contains because there is no __not_contains__ 
special method. (Your point two, which I disagree with.)



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.


 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.


 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


Re: Feature Request: `operator.not_in`

2013-04-19 Thread Matthew Gilson


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