0

I have always thought that using -1 in a condition is alway the same as the writing False (boolean value). But from my code, I get different results:

Using True and False:

def count(sub, s):
    count = 0
    index = 0
    while True:
        if string.find(s, sub, index) != False:
            count += 1
            index = string.find(s, sub, index) + 1
        else:
            return count


print count('nana', 'banana')

Result: Takes to long for interpreter to respond.


Using 1 and -1:

def count(sub, s):
    count = 0
    index = 0
    while 1:
        if string.find(s, sub, index) != -1:
            count += 1
            index = string.find(s, sub, index) + 1
        else:
            return count


print count('nana', 'banana')

Result: 1

Why does using -1 and 1 give me the correct result whereas using the bool values True and False do not?

Adnan
  • 3,129
  • 6
  • 31
  • 36
  • possible duplicate of [Why does 1 == True but 2 != True in Python?](http://stackoverflow.com/questions/7134984/why-does-1-true-but-2-true-in-python) – agf Aug 21 '11 at 01:35
  • We just had a question about `True` and `False` in Python. `-1` is not `False` in Python, `0` is False. Please search for things like this before you post a question. – agf Aug 21 '11 at 01:35
  • Also see [python-true-false](http://stackoverflow.com/questions/5119709/python-true-false), [why-cant-python-handle-true-false-values-as-i-expect](http://stackoverflow.com/questions/2055029/why-cant-python-handle-true-false-values-as-i-expect), [is-false-0-and-true-1-in-python-an-implementation-detail-or-is-it-guarantee](http://stackoverflow.com/questions/2764017/is-false-0-and-true-1-in-python-an-implementation-detail-or-is-it-guarantee), [true-false-true](http://stackoverflow.com/questions/3606333/true-false-true) – agf Aug 21 '11 at 01:38
  • Regardless of the title, the problem here has nothing to do with the value of `True` and `False`. The title should be "why doesn't this code work" instead. – D.Shawley Aug 21 '11 at 01:47
  • @D.Shawley: worst. suggested. title. ever. – Wooble Aug 21 '11 at 04:11

4 Answers4

4

string.find doesn't return a boolean so string.find('banana', 'nana', index) will NEVER return 0 (False) regardless of the value of index.

>>> import string
>>> help(string.find)
Help on function find in module string:

find(s, *args)
    find(s, sub [, start [, end]]) -> int

    Return the lowest index in s where substring sub is found,
    such that sub is contained within s[start,end].  Optional
    arguments start and end are interpreted as in slice notation.

    Return -1 on failure.
>>>

Your example simply repeats:

index = string.find('banana', 'nana', 0) + 1 # index = 3
index = string.find('banana', 'nana', 3) + 1 # index = 0

The -1 version works because it correctly interprets the return value of string.find!

D.Shawley
  • 58,213
  • 10
  • 98
  • 113
2

False is of type bool, which is a sub-type of int, and its value is 0.

In Python, False is similar to using 0, not -1

pythonquick
  • 10,789
  • 6
  • 33
  • 28
1

There's a difference between equality and converting to a boolean value for truth testing, for both historical and flexibility reasons:

>>> True == 1
True
>>> True == -1
False
>>> bool(-1)
True
>>> False == 0
True
>>> bool(0)
False
>>> True == 2
False
>>> bool(2)
True
Ross Patterson
  • 5,702
  • 20
  • 38
0

I have always thought that using -1 in a condition is alway the same as the writing False (boolean value).

1) No. It is never the same, and I can't imagine why you would have ever thought this, let alone always thought it. Unless for some reason you had only ever used if with string.find or something.

2) You shouldn't be using the string module in the first place. Quoting directly from the documentation:

DESCRIPTION
Warning: most of the code you see here isn't normally used nowadays. Beginning with Python 1.6, many of these functions are implemented as methods on the standard string object. They used to be implemented by a built-in module called strop, but strop is now obsolete itself.

So instead of string.find('foobar', 'foo'), we use the .find method of the str class itself (the class that 'foobar' and 'foo' belong to); and since we have objects of that class, we can make bound method calls, thus: 'foobar'.find('foo').

3) The .find method of strings returns a number that tells you where the substring was found, if it was found. If the substring wasn't found, it returns -1. It cannot return 0 in this case, because that would mean "was found at the beginning".

4) False will compare equal to 0. It is worth noting that Python actually implements its bool type as a subclass of int.

5) No matter what language you are using, you should not compare to boolean literals. x == False or equivalent is, quite simply, not the right thing to write. It gains you nothing in terms of clarity, and creates opportunities to make mistakes.

You would never, ever say "If it is true that it is raining, I will need an umbrella" in English, even though that is grammatically correct. There is no point; it is not more polite nor more clear than the obvious "If it is raining, I will need an umbrella".

If you want to use a value as a boolean, then use it as a boolean. If you want to use the result of a comparison (i.e. "is the value equal to -1 or not?"), then perform the comparison.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153