Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Python: Python

Logic operators with "in" statement

 

 

Python python RSS feed   Index | Next | Previous | View Threaded


mr.spoon21 at gmail

Nov 16, 2009, 6:02 AM

Post #1 of 12 (518 views)
Permalink
Logic operators with "in" statement

Hi,
I'm trying to use logical operators (or, and) with the "in" statement,
but I'm having some problems to understand their behavior.

In [1]: l = ['3', 'no3', 'b3']

In [2]: '3' in l
Out[2]: True

In [3]: '3' and '4' in l
Out[3]: False

In [4]: '3' and 'no3' in l
Out[4]: True

This seems to work as I expected.
------------

In [5]: '3' and 'no3' or '3' and '4' in l
Out[5]: 'no3'

In [6]: ('3' and 'no3') or ('3' and '4') in l
Out[6]: 'no3'

I don't understand these outputs.
---------------

In [7]: (('3' and 'no3') or ('3' and '4')) in l
Out[7]: True

In [10]: (('b3' and '4') or ('3' and 'no3')) in l
Out[10]: False

Here I expected to get True in the second case too, so clearly I don't
really get how they work.

Can you help me?
What I really need is to create a sequence of "if" statements to check
the presence of elements in a list, because some of them are mutually
exclusive, so if for example there are both "3" and "no3" it should
return an error.

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


mr.spoon21 at gmail

Nov 16, 2009, 6:08 AM

Post #2 of 12 (496 views)
Permalink
Re: Logic operators with "in" statement [In reply to]

Sorry for replying to myself, but I think I understood why I was wrong.

The correct statement should be something like this:

In [13]: ('b3' and '5') in l or ('3' and 'b3') in l
Out[13]: True
--
http://mail.python.org/mailman/listinfo/python-list


exarkun at twistedmatrix

Nov 16, 2009, 6:12 AM

Post #3 of 12 (497 views)
Permalink
Re: Logic operators with "in" statement [In reply to]

On 02:02 pm, mr.spoon21 [at] gmail wrote:
>Hi,
>I'm trying to use logical operators (or, and) with the "in" statement,
>but I'm having some problems to understand their behavior.

"and" and "or" have no particular interaction with "in".
>
>In [1]: l = ['3', 'no3', 'b3']
>
>In [2]: '3' in l
>Out[2]: True
>
>In [3]: '3' and '4' in l
>Out[3]: False
>
>In [4]: '3' and 'no3' in l
>Out[4]: True
>
>This seems to work as I expected.

What this actually does is '3' and ('no3' in l). So it might have
produced the result you expected, but it didn't work how you expected.
:)

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


R.Brodie at rl

Nov 16, 2009, 6:17 AM

Post #4 of 12 (472 views)
Permalink
Re: Logic operators with "in" statement [In reply to]

"Mr.SpOOn" <mr.spoon21 [at] gmail> wrote in message
news:mailman.492.1258380560.2873.python-list [at] python

> In [13]: ('b3' and '5') in l or ('3' and 'b3') in l
> Out[13]: True

For anything more than the simplest cases, you might want use sets.

That might be the correct data type from the start, depending on
whether the ordering is important anywhere.


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


clp2 at rebertia

Nov 16, 2009, 6:21 AM

Post #5 of 12 (498 views)
Permalink
Re: Logic operators with "in" statement [In reply to]

On Mon, Nov 16, 2009 at 6:02 AM, Mr.SpOOn <mr.spoon21 [at] gmail> wrote:
> Hi,
> I'm trying to use logical operators (or, and) with the "in" statement,
> but I'm having some problems to understand their behavior.
>
> In [1]: l = ['3', 'no3', 'b3']
>
> In [2]: '3' in l
> Out[2]: True
>
> In [3]: '3' and '4' in l
> Out[3]: False
>
> In [4]: '3' and 'no3' in l
> Out[4]: True
>
> This seems to work as I expected.

No, it doesn't. You are misinterpreting. Membership tests via `in` do
NOT distribute over `and` and `or`.

'3' and '4' in l
is equivalent to:
('3') and ('4' in l)

Recall that non-empty sequences and containers are conventionally True
in Python, so your expression is logically equivalent to:
'4' in l
With '3' not being checked for membership at all.

To check multiple items for membership in a contains, you must write
each `in` test separately and then conjoin then by the appropriate
boolean operator:

'3' in l and '4' in l

Cheers,
Chris
--
http://blog.rebertia.com
--
http://mail.python.org/mailman/listinfo/python-list


contact at xavierho

Nov 16, 2009, 6:23 AM

Post #6 of 12 (499 views)
Permalink
Re: Logic operators with "in" statement [In reply to]

On Tue, Nov 17, 2009 at 12:02 AM, Mr.SpOOn <mr.spoon21 [at] gmail> wrote:

> Hi,
> I'm trying to use logical operators (or, and) with the "in" statement,
> but I'm having some problems to understand their behavior.
>

Hey Carlo, I think your issue here is mistaking 'in' as a statement. It's
just another logic operator, much like 'and' and 'or'... it's not a
statement in itself. At least, I don't think that's how you'd call 'in'.

You have to remember that Python's logical operators (and, or) works
slightly different than most languages. It doesn't return True or False, if
the things compared aren't boolean values. Instead, it returns the first
thing that makes the decision.

For example a statement such as

>>>'3' and '4'
'4'

returns the string literal 4.

1.
Python's AND operator returns the first element if the first one is False;
else, it returns the second element. That's all it does.

Python's OR operator returns the first element if the first one is True;
else, it returns the second element.

Think about it. It's a little strange, but they don't return a pure Boolean
value.

2.
Only the empty string is considered False. Any non-empty strings have True
values.

3.
The proper way of using the in operator is probably such: (There may be a
better way I'm not aware of.)

>>> '3' in l and '4' in l
False

>>> '3' in l and 'no3' in l
True

AND operator has a higher precedence, so you don't need any brackets here, I
think. But anyway, you have to use it like that. So that's something you'll
have to fix first.



> What I really need is to create a sequence of "if" statements to check
> the presence of elements in a list, because some of them are mutually
> exclusive, so if for example there are both "3" and "no3" it should
> return an error


One idea I can think of is to have a presence count; assuming the input is
non-repeating, you increase this count by 1, starting at 0. If you get
anything above one, return this error you speak of, and that might be a good
start.

Good luck,
Xav


clp2 at rebertia

Nov 16, 2009, 6:30 AM

Post #7 of 12 (499 views)
Permalink
Re: Logic operators with "in" statement [In reply to]

On Mon, Nov 16, 2009 at 6:08 AM, Mr.SpOOn <mr.spoon21 [at] gmail> wrote:
> Sorry for replying to myself, but I think I understood why I was wrong.
>
> The correct statement should be something like this:
>
> In [13]: ('b3' and '5') in l or ('3' and 'b3') in l
> Out[13]: True

No, you've just run into another misunderstanding.

Given the expression `X and Y`:
If bool(X) is False, it evaluates to X.
Otherwise, it evaluates to Y.

In other words, the subexpression which ends up determining the truth
of the conjunction is what the conjunction evaluates to. `or` works
similarly.
This allows for tricky tricks like:
foo = possiblyFalse or default # use default if given value is false

Thus, due to the parentheses, your expression is equivalent to:
'5' in l or 'b3' in l
Which I trust is not what you intended.

Again, you need to write separate `in`s for each item you need to
check the membership of:
('b3' in l and '5' in l) or ('3' in l and 'b3' in l)

Cheers,
Chris
--
Python language lawyer at your service
http://blog.rebertia.com
--
http://mail.python.org/mailman/listinfo/python-list


contact at xavierho

Nov 16, 2009, 6:30 AM

Post #8 of 12 (497 views)
Permalink
Re: Logic operators with "in" statement [In reply to]

On Tue, Nov 17, 2009 at 12:08 AM, Mr.SpOOn <mr.spoon21 [at] gmail> wrote:

> Sorry for replying to myself, but I think I understood why I was wrong.
>
> The correct statement should be something like this:
>
> In [13]: ('b3' and '5') in l or ('3' and 'b3') in l
> Out[13]: True
>
>
Carlo, I'm not sure what that achieves. Care to enlighten me?

Cheers,
Xav


python.list at tim

Nov 16, 2009, 6:38 AM

Post #9 of 12 (500 views)
Permalink
Re: Logic operators with "in" statement [In reply to]

> Here I expected to get True in the second case too, so clearly I don't
> really get how they work.

You're seeing short-circuit evaluation:

>>> "3" or "4" # true
'3'
>>> '4' or '3' # true
'4'
>>> '4' in l # false
False
>>> '3' or False # true
'3'
>>> '4' or '42' in l # true: same as "'4' or ('42' in l)"
'4'
>>> '4' or '42'
'4'
>>> ('4' or '42') in l # true: same as "'4' in l"
'4'

It just happens that sometimes you get unexpected results that
happen to be right because of how Python handles strings/numbers
as booleans and order-of-operations.

> What I really need is to create a sequence of "if" statements to check
> the presence of elements in a list, because some of them are mutually
> exclusive, so if for example there are both "3" and "no3" it should
> return an error.

The "in" operator only checks containment of one item, not
multiples, so you have to manage the checking yourself. This is
fairly easy with the any()/all() functions added in 2.5:

any(i in l for i in ("3", "4"))
all(i in l for i in ("3", "4"))

For more complex containment testing, using sets will be more
efficient and offers a richer family of batch operators
(contains, intersection, union, difference, issubset, issuperset)

-tkc




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


clp2 at rebertia

Nov 16, 2009, 6:46 AM

Post #10 of 12 (497 views)
Permalink
Re: Logic operators with "in" statement [In reply to]

On Mon, Nov 16, 2009 at 6:23 AM, Xavier Ho <contact [at] xavierho> wrote:
<snip>
>>>> '3' in l and 'no3' in l
> True
>
> AND operator has a higher precedence, so you don't need any brackets here, I
> think. But anyway, you have to use it like that. So that's something you'll
> have to fix first.

Er, you mean lower precedence. Higher precedence means it would bind
tighter, thus the expression would mean:
'3' in (l and 'no3') in l
which is certainly incorrect.

Cheers,
Chris
--
http://blog.rebertia.com
--
http://mail.python.org/mailman/listinfo/python-list


contact at xavierho

Nov 16, 2009, 4:32 PM

Post #11 of 12 (483 views)
Permalink
Re: Logic operators with "in" statement [In reply to]

On Tue, Nov 17, 2009 at 12:46 AM, Chris Rebert <clp2 [at] rebertia> wrote:

> On Mon, Nov 16, 2009 at 6:23 AM, Xavier Ho <contact [at] xavierho> wrote:
> > AND operator has a higher precedence, so you don't need any brackets
> here, I
> > think. But anyway, you have to use it like that. So that's something
> you'll
> > have to fix first.
>
> Er, you mean lower precedence. Higher precedence means it would bind
> tighter, thus the expression would mean:
> '3' in (l and 'no3') in l
> which is certainly incorrect.
>
>
Thanks for the correction, Chris.

Cheers,
Xav


mr.spoon21 at gmail

Nov 17, 2009, 4:00 AM

Post #12 of 12 (476 views)
Permalink
Re: Logic operators with "in" statement [In reply to]

Thanks everybody for all the answers and explanations.

In the end maybe it is simpler if I use sets for these tests.

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

Python python RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.