Each Answer to this Q is separated by one/two green lines.
def find_str(s, char)
and a string:
I essentially want to input
"py" and return
3 but I keep getting
2 to return instead.
def find_str(s, char): index = 0 if char in s: char = char for ch in s: if ch in s: index += 1 if ch == char: return index else: return -1 print(find_str("Happy birthday", "py"))
Not sure what’s wrong!
There’s a builtin method find on string objects.
s = "Happy Birthday" s2 = "py" print(s.find(s2))
Python is a “batteries included language” there’s code written to do most of what you want already (whatever you want).. unless this is homework 🙂
find returns -1 if the string cannot be found.
Your problem is your code searches only for the first character of your search string which(the first one) is at index 2.
You are basically saying if
char is in
ch == char which returned 3 when I tested it but it was still wrong. Here’s a way to do it.
def find_str(s, char): index = 0 if char in s: c = char for ch in s: if ch == c: if s[index:index+len(char)] == char: return index index += 1 return -1 print(find_str("Happy birthday", "py")) print(find_str("Happy birthday", "rth")) print(find_str("Happy birthday", "rh"))
It produced the following output:
3 8 -1
There is one other option in regular expression, the
import re string = 'Happy Birthday' pattern = 'py' print(re.search(pattern, string).span()) ## this prints starting and end indices print(re.search(pattern, string).span()) ## this does what you wanted
By the way, if you would like to find all the occurrence of a pattern, instead of just the first one, you can use
import re string = 'i think that that that that student wrote there is not that right' pattern = 'that' print([match.start() for match in re.finditer(pattern, string)])
which will print all the starting positions of the matches.
Adding onto @demented hedgehog answer on using
In terms of efficiency
It may be worth first checking to see if s1 is in s2 before calling
This can be more efficient if you know that most of the times s1 won’t be a substring of s2
in operator is very efficient
s1 in s2
It can be more efficient to convert:
index = s2.find(s1)
index = -1 if s1 in s2: index = s2.find(s1)
This is useful for when
find() is going to be returning -1 a lot.
I found it substantially faster since
find() was being called many times in my algorithm, so I thought it was worth mentioning
Here is a simple approach:
my_string = 'abcdefg' print(text.find('def'))
I the substring is not there, you will get -1.
my_string = 'abcdefg' print(text.find('xyz'))
Sometimes, you might want to throw exception if substring is not there:
my_string = 'abcdefg' print(text.index('xyz')) # It returns an index only if it's present
Traceback (most recent call last):
File “test.py”, line 6, in
ValueError: substring not found
late to the party, was searching for same, as “in” is not valid, I had just created following.
def find_str(full, sub): index = 0 sub_index = 0 position = -1 for ch_i,ch_f in enumerate(full) : if ch_f.lower() != sub[sub_index].lower(): position = -1 sub_index = 0 if ch_f.lower() == sub[sub_index].lower(): if sub_index == 0 : position = ch_i if (len(sub) - 1) <= sub_index : break else: sub_index += 1 return position print(find_str("Happy birthday", "py")) print(find_str("Happy birthday", "rth")) print(find_str("Happy birthday", "rh"))
3 8 -1
remove lower() in case case insensitive find not needed.
Not directly answering the question but I got a similar question recently where I was asked to count the number of times a sub-string is repeated in a given string. Here is the function I wrote:
def count_substring(string, sub_string): cnt = 0 len_ss = len(sub_string) for i in range(len(string) - len_ss + 1): if string[i:i+len_ss] == sub_string: cnt += 1 return cnt
The find() function probably returns the index of the fist occurrence only. Storing the index in place of just counting, can give us the distinct set of indices the sub-string gets repeated within the string.
Disclaimer: I am ‘extremly’ new to Python programming.