I recently wrote a Python program that used:
if s.find('something'):
or
if s.find('something')==True:
but nothing worked correctly until I used:
if s.find('something') >0
That's the only way I could get an accurate True decision in my program.
It seems -1 result wasn't recognized as False. Successful finds weren't recognized as True either. So looking for -1 (False) or a positive number >0 (True) was the only thing that worked for me.
What was I doing wrong? This can't be the way Python works, can it?
You are interpreting the return value of find
incorrectly. The documentation states:
str.find(sub[, start[, end]])
Return the lowest index in the string where substring
sub
is found, such thatsub
is contained in the slices[start:end]
. Optional arguments start and end are interpreted as in slice notation. Return-1
ifsub
is not found.
Of all numbers, Python considers only 0 to be false; -1 is true . As find
returns the index of the beginning of the match, and 0 is a valid index to a string, -1 is returned when no match was found.
Thus your code should rather* be:
if s.find('something') != -1:
or
if s.find('something') >= 0:
Though they're not the most Pythonic either, if you just want to see if s
contains 'something'
- see below.
Now, about your second example: the bool
constant False
compares equal to 0
:
>>> 0 == False
True
and bool
constant True
only equal to number 1
:
>>> 1 == True
True
>>> 2 == True
False
Thus the expression s.find('something') == True
would be totally equivalent with s.find('something') == 1
; and the whole expression would evaluate to True
only if the s
would be of form xsomethingxxxx
, with a match for something
starting at the 2nd character (index 1).
The documentation for str.find
continues with the following note:
Note
The
find()
method should be used only if you need to know the position ofsub
. To check ifsub
is a substring or not, use thein
operator:>>> 'Py' in 'Python' True
Thus the form that is the most Pythonic for the problem in your question is
if 'something' in s:
As suggested by @myaut, if you need the position of 'something'
within s
and expect it to contain the value, you should use str.index
instead, which will throw an exception if the substring
was not found within the string.
try:
position = s.index('something')
print("'something' found at", position)
except ValueError:
print(s, "does not contain the substring 'something'")
Python thinks 0
is False
, not -1
.
As you can see in the Python documentation , Python tries hard to have many different kinds of False
values:
False
None
0
of any numeric type: 0
, 0L
, 0.0
, 0j
. ''
, ()
, []
. {}
. Your intuitive notion that -1
should be False
in Python makes some sense, but that is just not how Python was designed. Zeros and empties are falsey in Python.
If you only want to check wether a string is contained in another, use:
if 'something' in s:
print 'something in %s' % s
else:
print 'bad luck'
-1
as an error code came from C, but that leads to spaghetti code of checking return values.
Python has more reliable way to report an error: raise an Exception . Ie str.index
does that:
>>> 'abcde'.find('cd')
2
>>> 'abcde'.index('cd')
2
>>> 'abcde'.find('zx')
-1
>>> 'abcde'.index('zx')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: substring not found
And of course to check if string contains substring you should use in
operator:
>>> 'ab' in 'abcde'
True
>>> 'zx' in 'abcde'
False
Speaking of if
statements you should note that comparing to boolean is a bad idea (check for example PEP-8 ).
Every type in Python defines its own rules which values are considered "True": Truth value testing
The quickest way to verify what is the bool value of it;
bool(-1)
True
bool(0)
False
bool('')
False
and so on,
You are not doing something wrong.
In python bool
inherit from int
. False
is 0
and True
is 1
. You can try int(True)
and int(False)
. If you try bool(0)
you will get False
, but if you write bool(-1)
or bool(1)
you always will get True
. If you use find
you will get -1
so you need to use >= 0
. You can find 'something'
inside 'something else'
.
You can write if 'something' in s:
. I think that find is deprecated.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.