Domanda

def test_string_membership():
    assert False == 'c' in 'apple'
    assert True == 'a' in 'apple'
    assert True == 'app' in 'apple'

p.s:- I am a beginner in python and unable to find out whats wrong. My assertion fails when I run the code.

È stato utile?

Soluzione

False == 'c' in 'apple' is not interpreted as

False == ('c' in 'apple')

but,

(False == 'c') and ('c' in apple)

becaue of comparison chaining.


To get what you want, put parentheses explicitly.

False == ('c' in 'apple')

or more preferably use in / not in:

def test_string_membership():
    assert 'c' not in 'apple'
    assert 'a' in 'apple'
    assert 'app' in 'apple'

Altri suggerimenti

You have a problem with comparison chaining, the Python syntax that treats:

x < y < z

as:

x < y and y < z.

In your case, that means the expression False == 'c' in 'apple' is being treated as:

(False == 'c') and ('c' in 'apple')

both of which are false, hence causing the assertion. Details on comparison chaining for Python 3 can be found here.

So the way to avoid this chianing is to make the expression explicit, with something like:

assert False == ('c' in 'apple')
assert True == ('a' in 'apple')
assert True == ('app' in 'apple')

or, even better, since comparing with true/false is rarely a good idea:

assert 'c' not in 'apple' # or "not('c' in 'apple')" if you're testing 'in'.
assert 'a' in 'apple'
assert 'app' in 'apple'

Contrary to the other answers, what is happening here is not operator precedence but comparison chaining. a == b in c means (a == b) and (b in c), just like a < b < c means (a < b) and (b < c). However, in either case, the upshot is the same, which is that it's not what you meant to do. As noted in the other answers and comments, it can be fixed by using parentheses, or, better, by not using an equality comparison at all and just doing assert 'c' not in 'apple'.

You can see that this is comparison chaining by a slightly different example:

>>> 'a' == 'a' in 'ab'
True

This would obviously be false no matter which way the precedence went, but it is true because 'a' == 'a' and 'a' in 'ab' are both true.

Using parenthesis should solve this as in

def test_string_membership():
    assert False == ('c' in 'apple')
    assert True == ('a' in 'apple')
    assert True == ('app' in 'apple')

You may use () in this case. There are better ways to do what you are trying.

def test_string_membership():
    assert False == ('c' in 'apple')
    assert True == ('a' in 'apple')
    assert True == ('app' in 'apple')

This is because of precedence. Read more about this on Python docs.

in, not in, is, is not, <, <=, >, >=, <>, !=, == are in the same precedence level. So Python will evaluate

False == 'c' in 'apple'

from left to right.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top