0

I'm trying to write a simple function in python to do what in or str.contains does, here are the codes:

def contains(big, little):
  length = len(little_string)
  for i in big:
    if big[i:i+length-1] == little:
      return True
  return False

For line if big[i:i+length-1] == little:`` it throws a TypeError saying must be str not int and I'm baffled. Since I think as long as big is a string the slicing of it will certainly be string too.

Does anyone know why this happened? thanks a lot.

4
  • 2
    if big is a str, then for i in big will yield characters of the string Commented Jan 8, 2020 at 3:31
  • Please include an example of how you called the function and the fill error message. You most probably wanted to write for i in len(big). Commented Jan 8, 2020 at 3:32
  • @DYZ for i in range(len(big)). Commented Jan 8, 2020 at 4:26
  • @chepner Sure... Commented Jan 8, 2020 at 6:02

2 Answers 2

1

I think what you're looking for is to iterate over a range, not over the string big itself:

big = 'abcd'

for i in big:
    print(i)
a
b
c
d

for i in range(len(big)):
    print(i)
0
1
2
3

This is what's causing your error, you are passing characters of big into your slice and then adding them to int. The TypeError is from the addition of the two, not the slice:

'a' + 1
TypeError: must be str, not int

big = 'abcd'
big['a': 'a'+1]
TypeError: must be str, not int

To fix this, create a range(len(big)) which produces those integer indices, which match the types, and the slice will work:

def contains(big, little):
    l = len(little)
    ## Do this instead
    # i is now an int in the range of len(big)
    for i in range(len(big)):
        if b[i:i + l] == little:
            return True
    return False

You also don't need the -1 in your slice, since slicing will not produce an IndexError

Sign up to request clarification or add additional context in comments.

1 Comment

yes i just realised that ! thanks so much for the clarifying example
0

There are couple of little errors in the code you show us. For starters, a typo where you calculate len(little_string) while your parameter is called little.

The core of the issue as you describe is because for in in big effectively loops through the characters of the big string, which is not what you want to do in the code. Since you are looking at moving by index, then you should rather do something like this:

def contains(big, little):
    length = len(little)                 # fix the typo
    for i in range(len(big)):            # this generates list of indices [0,1,2...]
        if big[i:i + length] == little:  # note we fixed it removing -1
            return True
    return False

# test
needle = 'one'
haystack = 'dragone'

print(contains(haystack, needle))
>> True

1 Comment

thanks so much for the explanation (and the little notes)!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.