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'.
Related
I found this piece of code from a related question about reversing strings in python, but can someone please interpret it in plain English? Please note that I am still new to python and only learnt how to use while loops and functions yesterday :/ so I cant really put this into words myself cause my understanding isn't quite there yet.
anyways here is the code:
def reverse_string(string):
new_strings = []
index = len(string)
while index:
index -= 1
new_strings.append(string[index])
return ''.join(new_strings)
print(reverse_string('hello'))
Surely by knowing what it does, you can figure the code. In the while loop, the index value starts from the end of the string and counts down to 0. In each step, it adds that character (again, starting from the end) to the end of the list it is building. Finally, it combines the list into a string.
So, given 'abcd', the list gets built:
'abcd' #3 -> ['d']
'abcd' #2 -> ['d','c']
'abcd' #1 -> ['d','c','b']
'abcd' #0 -> ['d','c','b','a']
Well basically, the get the length of the string with the len method. Which will return you an integer value representing how long that string is.
They then use the length of this string and effectively iterate down to zero in a while loop. Using the -= operator.
Each iteration (meaning each time around the loop) it will take away from length until it reaches zero.
So lets use hello as an example input and go through this together.
reverse_string('hello') is how we would call the method, done in the print statement of your code.
We then enter the function and perform these steps:
We create a new empty array called new_strings.
We find the length of the initial string hello which returns us 5. Meaning that now index is equal to 5.
We create a while loop that keeps on going until index is no more using while(index): - a while loop like this treats a 0 value as falsy and will terminate upon reaching this. Therefore when index is 0 the loop will stop.
The first line of this loop performs index -= 1 which is the same as writing index = index - 1 so the very first loop through we get index = 5 - 1 and then now index is equal to 4.
Because Python then lets us access the character of a string using string[index] (and because this works from 0 -> n) performing hello[4] will in fact give us the character o.
We also append this character to the array new_strings meaning that as we go through the iterations to reach zero it will add each character backwards to this array giving us ['o', 'l', 'l', 'e', 'h']
Since index is now zero we leave the loop and perform a join operation on the array to yet again create a string. The command ''.join(new_strings) means that we wish to join the array we previously had without a separator. If we had done '#'.join(new_strings) we instead would have gotten o#l#l#e#h instead of olleh.
I hope this answer gives you some clarity.
Sure, It is very simple program. You should reffer string methods and string indexing in python to get clear idea. Let me explain this in deatial.
print(reverse_string('hello'))//The print function is calling another function
reverse_string and passing argument"hello".
def reverse_string(string):// The argument "hello" is stored in the variable
string in reverse_string function.
**new_strings = []** // created a new empty list
**index = len(string)** // len function returns the length of the argument
passed to the function. len("hello")=5 and assigned
to index. index=5.
while index: // while loop exicute until the condition get false .In this
example when index =0.in string the indexing start from 0 .For
example.
string[0]=h,string[1]=e,string[2]=l,string[3]=l,string[4]=o.
**index -= 1** //Note the last letter 'o' is in string[4] and the len
function returned 5 so we need to decrement index variable
to 4 so that it will pointing to string[4]=o
new_strings.append(string[index]) // append string[4] that is o and so on ...
return ''.join(new_strings)
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.
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
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.
find('asdf','') finds an empty string in 'asdf' hence it returns 0.
Similarly, find('asdf','',3) starts to search for the string at index position 3 and hence return 3.
Since the last index is 3, find('asdf','',4) should return -1 but it returns 4 and starts to return -1 only if the starting index is more than or equal to (last_index)+2. Why is this so?
Because "asdf" without its first four characters still does contain "". A harder check comes into play when the index exceeds the length of the string, but having an index equal to the string is equivalent to "".find().
Here is how it works:
0 a 1 s 2 d 3 f 4
When you use 'asdf'.find(sub), it searches those five positions, labeled 0, 1, 2, 3, and 4. Those five. Those five. No more and no less. It returns the first one where 'asdf'[pos:pos+len(sub)] == sub. If you include the start argument to find, it starts at that position. That position. Not one less, not one more. If you give a start position greater than the greatest number in the list of positions, it returns -1.
In other words, the answer is what I already repeated in a comment, quoting another question answer:
The last position [for find] is after the last character of the string
Edit: it seems your fundamental misunderstanding relates to the notion of "positions" in a string. find is not returning positions which you are expected to access as individual units. Even if it returns 4, that doesn't mean the empty string is "at" position 4. find returns slice starts. You are supposed to slice the string starting at the given position.
So when you do 'asdf'.find('', 4), it starts at position 4. It finds the empty string there because 'asdf'[4:4+len('')]==''. It returns 4. That is how it works.
It is not intended that str.find has a one-to-one mapping between valid indexes into the actual string. Yes, you can do tons of other indexing like 'asdf'[100:300]. That is not relevant for find. What you know from find is that 'asdf'[pos:pos+len(sub)] == sub. You do not know that every possible index that would return '' will be returned by find, nor are you guaranteed that the number returned by find is a valid index into the string if you searched for an empty string.
If you have an actual question about some use of this functionality, then go ahead and ask that as a separate question. But you seem to already know how find works, so it's not clear what you're hoping to gain from this question.