I was looking at a solution to a question at geeksforgeeks and I stumbled upon the function index() and rindex().
Below is part of the code and I was wondering whether the code has an error. Is it possible for index() and rindex() to even be -1? If the string does not contain the substring, doesn't it return an error?
# find index of last occurrence of
# character x in the input string
last = string.rindex(x)
# find index of first occurrence of
# character y in the input string
first = string.index(y)
# return false if x or y are not present
# in the input string OR last occurrence of
# x is after the first occurrence of y
# in the input string
if last == -1 or first == -1 or last > first:
return False
The code snippet you shared seems to be wrong. index will indeed raise a ValueError if the substring isn't found (unlike find that will return -1).
string.index returns ValueError when it did not find the substring.
string.find returns -1 when it did not find the substring.
refer to this link
Related
Was doing a question from the Python section of codecademy. Came across this question. I did solve it but I checked their hint afterwards to know and understand their way of doing things. Didn't really get it. Could someone please explain it to me?
This is the question:
"Write a function named substring_between_letters that takes a string named word, a single character named start, and another character named end. This function should return the substring between the first occurrence of start and end in word. If start or end are not in word, the function should return word."
For example, substring_between_letters("apple", "p", "e") should return "pl"
This was the hint they gave that I didn't understand and need explaining:
"Begin by finding the indices of the start and end characters by using word.find(start) and word.find(end).
If either of those indices are -1, then the original string didn’t contain one of those characters, and you should return word.
If neither are -1, then slice word using those indices. Remember, slicing is [inclusive:exclusive]!"
Just didn't get the part about the negative indices. I know what negative indices are but how does it matter in this context?
str. find returns -1 if the character is not found. They're saying you should check for that case first before continuing.
Maybe the following code will make it clearer -
def substring_between_letters(word, s, e):
i = word.find(s), word.find(e)
if -1 in i:
return word
else:
return word[i[0]+1:i[1]]
print(substring_between_letters('apple', 'p','e'))
#OUTPUT - 'pl'
print(substring_between_letters('hello', 'p','e'))
#OUTPUT - 'hello'
What you need to do is to get the substring between the start index and the end index, which you can find by doing word.find(). But since the first index will be inclusive and the second one is exclusive, you have to start from start_index +1 to end_index to get the string in between after exluding the starting and ending character. If any of the characters is not present, then word.find returns a -1. In that case, you can simply return the whole word.
In python slicing ' If the first index is greater than or equal to the second the result is an empty string ' then why the following operation return string?
>>> msg = 'HelloWorld'
>>> msg[4:-2]
'oWor'
The quote you gave is either incorrect or incomplete:
If a negative number is used, it will be used as the reverse index on the file, meaning that [4:-2] is equivalent to [4:len(msg)-2] ie [4:8]
Note that if you use the reverse index to go further that the first index, you will indeed have an empty string.
msg[4:-8] # Equivalent to msg[4:1], by the same formula
>>> ''
Negative numbers in python slicing effectively work backwards from positive. They start at the end of the string and move forward. So what your code says is give me a string starting at the 4th index and goes until 2 from the end.
Indexes if negative they count from right. -1 is the last character. To access string from right index position we need to use - with index number. So for -2, it will be like take character till before l (for given example) and its total length must be 4. So it will be owor only.
Testing if a string is a palindrome or not and should be O(n) runtime. We cannot use any import statements or any other helper methods can be used.
So basically my program is to receive an input which is a string that can contain anything. If something in that string is not part of the alphabet it is to ignore it, such as spaces or commas. My program currently works but seems like there should be ways that I could make my program better, by either reducing code or something that I am just unaware of.
An example would be with the string ' E.U.V, vV V,U,E' so the first thing mine does is it goes to string[0] which is just a space and shorts to recalling itself with isPalindrome(string[1]:len(string)-1) so isPalindrome('E.U.V, vV V,U,E').
def isPalindrome (string):
if len(string) <=1: # Basecase to check if the string has less than or equal to 1 element remaining in the string so that the recursion may end
return True
if string.isalpha(): # Checks if the string is all letters of the alphabet and proceeds if true
if (string[0].lower() == string[len(string)-1].lower()): # Compares the lowercase form of the first element and the last element and if they are equal the program will proceed
return isPalindrome(string[1:len(string)-1]) # Function is calling itself with the next elements in the string
else:
return False
else:
if string[0].isalpha(): # Checks if the first element in the string is part of the alphabet and proceeds if true
if string[len(string)-1].isalpha(): # Checks if the last element of the string is part of the element and proceeds if true
if (string[0].lower()== string[len(string)-1].lower()): # Both the first and last element have been confirmed as being part of the alphabet and will not be compared to each other, program proceeds if true
return isPalindrome(string[1:len(string)-1]) # Function is calling itself with the next elements in the string
else:
return False # Program return false when some elements do not equal each other
else:
return isPalindrome(string[0:len(string)-1]) # Function is calling itself with the next elements in the string
else:
return isPalindrome(string[1:len(string)]) # Function is calling itself with the next elements in the string
Well, that is a lot of code for palindrome checking.
Essentially, a palindrome is a string that equals itself if read from the end. You can check that with the slice notation on strings. Now to clean your string from everything that is not a letter, a small list comprehension will do.
def isPalindrome(text):
text = "".join([x for x in text if x.isalpha()])
return text==text[::-1]
in my code im having a problem because i cannot compare to list as i wanted. what i try to do is looking for first indexes of inputs firstly and then if indexes not the same looking for the next index of the longer input as i guess1. and then after finishing comparing the first index of elements i want to compare second indexes .. what i mean first checking (A-C)(A-A)(A-T) and then (C-A)(C-T).. and then (T-T)...
and want an input list as (A,T) beacuse of ATT part of guess1..
however i stuck in a moment that i always find ACT not A and T..
where i am wrong.. i will be very glad if you enlighten me..
edit..
what i'm trying to do is looking for the best similarity in the longer list of guess1 and find the most similiar list as ATT
GUESS1="CATTCG"
GUESS2="ACT"
if len(str(GUESS1))>len(str(GUESS2)):
DNA_input_list=list((GUESS1))
DNA_input1_list=list((GUESS2))
common_elements=[]
i=0
while i<len(DNA_input1_list)-1:
j=0
while j<len(DNA_input_list)-len(DNA_input1_list):
if DNA_input_list[i] == DNA_input1_list[j]:
common_elements.append(DNA_input1_list[j])
i+=1
j+=1
if j>len(DNA_input1_list)-1:
break
print(common_elements)
As far as I understand, you want to find a shorter substring in a longer substring, and if not found, remove an element from shorter substring then repeat the search.
You can use string find function in python for that. i.e. "CATTCG".find('ACT'), this function will return -1 because there are no substing ACT. What then you can do is remove an element from the shorter string using slice operator [::] and repeat the search like this --
>>> for x in range(len('ACT')):
... if "CATTCG".find('ACT'[x:]) > -1 :
... print("CATTCG".find('ACT'[x:]))
... print("Match found for " + 'ACT'[x:])
In code here, first a range of lengths is generated i.e. [0, 1, 2, 3] this is the number of items we're gonna slice off from the beginning.
In second line we do the slicing with 'ACT'[x:] (for x==0, we get 'ACT', for x == 1, we get 'CT' and for x==2, we get 'T').
The last two lines print out the position and the string that matched.
If I have understood everything correctly, you want to return the longest similar substring from GUESS2, with is included in GUESS1.
I would use something like this.
<!-- language: lang-py -->
for count in range(len(GUESS2)):
if GUESS2[:count] in GUESS1:
common_elements = GUESS2[:count]
print(GUESS2[:count]) #if a function, return GUESS2[:count]
A loop as long as the count from the searching string.
Then check if the substring is included in the other.
If so, save it to a variable and print/return it after the loop has finished.
Is it true that the last position of a string in python comes after the last character of that string?
If it is true does it mean if k='asdf' then at index position 4 there is a ''? If so, why doesn't k[4] return '' instead of out of range error.
It has been suggested to me to try k[4:4] to see this behavior but I think the slice returns a '' because it hasn't been given anything to contain and not specifically because of presence of a '' at the end of every string. If I do k[300:782], I still get '' but `find('asdf','',300)' returns -1 so this should confirm my beliefs.
That is not true. The last position in k='asdf' is k[3] with is 'f'.
You are also correct that when trying to examine a slice that doesn't contain anything (k[4:4] or k[300:2345] or k[6:5]) python will give you an empty result.
'' is an empty string; it is not returning a quotation mark.
#BrenBarn is absolutely right about find
Kyle does a great job of answering. I will only add that you can reference the last position of a string with the index -1. so in your example k[-1] produces 'f' just as k[3] produces 'f'.