This question already has answers here:
Understanding slicing
(38 answers)
Closed 8 years ago.
I am having a problem in understanding what happens when i put negative value to step in case of slicing.
I know [::-1] reverses a string. i want to know what value it assign to start and stop to get a reverse.
i thought it would be 0 to end to string. and tried
f="foobar"
f[0:5:-1]---> it gives me no output. why?
and i have read start should not pass stop. is that true in case of negative step value also?
can anyone help me to clear my doubt.
The reason why f[0:5:-1] does not generate any output is because you are starting at 0, and trying to count backwards to 5. This is impossible, so Python returns an empty string.
Instead, you want f[5:0:-1], which returns the string "raboo".
Notice that the string does not contain the f character. To do that, you'd want f[5::-1], which returns the string "raboof".
You also asked:
I have read start should not pass stop. is that true in case of negative step value also?
No, it's not true. Normally, the start value shouldn't pass the stop value, but only if the step is positive. If the step is negative, then the reverse is true. The start must, by necessity, be higher then the stop value.
You can think like that:
with f[0:5], 0 is the start position and 5-1 the end position.
with f[0:5:-1], 5 is the start position and 0+1 the end position.
In slicing the start position must be lower than the end position.
When this is not the case the result is an empty string. Thus f[0:5:-1] returns an empty string.
Related
I have a variabel s="Siva"
and I have tried doing slicing using a logic
s[0:-5:-1]
According to the concept of slicing I am going in the backward direction, so it should ideally start from "S" and then go to "a","v","i" However when i tried running this I am getting an output as only "S" and even when I tried using s[0:-100:-1] it is still showing "S". Can anyone explain why this is happening?
The step count given by you in s[0:-5:-1] is -1, which means that string slicing will be reverse like 'a','v','i','S'.
But you are starting from s[0] which is "S" and due to the step count -1,it will print the previous character from the string "Siva",But there are no characters before 'S'.That's why it's stopping and only printing 'S'.
If you want the reverse of s = "Siva",
then simply write s[::-1].
Slicing is s[start:end:step] so if you want Savi you have to do
s[0] + s[-1:0:-1]
Start at -1 means start at the end of the string.
End at 0 means end at the beginning ignoring this first character.
Step -1 means go reverse one at a time.
Indeed, slicing accepts [start:stop:step] in its syntax. What you're saying with [0, -5, -1] is "start at index 0; advance until index -4 (inclusive); and do so with steps of -1".
Your string is of length 4 and so index -4 is actually index 0: s[-4] would be 'S'.
In other words, you're basically saying: "start at index 0 and finish at index 0 (inclusive)", which is why you get only 'S'. Anything smaller than -5, for instance: -10, would also give you 'S' only because there's nowhere further to go: it's essentially the same as what would happen if you tried to do s[0:100000:1]: you'd simply get 'Siva', because your string is 4<100000 characters long, and Python's behaviour in such cases is to just return all four (or, more generally: return as many characters as it can in "the direction of iteration", based on the sign of your step parameter, before reaching the end of the string).
On the other hand, if you try something that is greater than -5, such as, say, -2 or even just a positive 3, you'd get an empty string: that's because you'd basically be saying "start at index -4 and advance in the negative direction until you reach something greater" – this is never expected to happen and is somewhat "gibberishy" in nature, and I guess the way Python chose to deal with it is to just return an empty string in those cases.
This was intended to answer your question of "why this happens" while granting some intuition, hopefully; when it comes to a solution, if what you want is to simply grab the first letter and then reverse the rest: I'd simply use s[0] + s[-1:0:-1]. For fun I'll note that another option would be s[0] + s[1:][::-1].
Slicing is used with [start:stop:step]. If you use negative numbers for start it will start at the specified index, from the end.
If you want to print "Savi", I think you must have to slices :
s="Siva"
s[0] + s[-1::-1]
Perhaps what you expected couldn't be done with a string slice, but could still be done with indexing.
>>> ''.join(s[i] for i in range(0,-5,-1))
'SaviS'
I hope this is a simple question! I am trying to reverse a number, and be given the digits in the 'even' positions. When I try to do this within one string slice, I am just given a single digit, even when I am expecing more. When I do it as two slices, I am given the correct answer, but I am unsure why.
For example, if I have the number 512341234, I would expect it to give me 3131, as I have first reversed the string (432143215) and then taken the even position numbers (4[3]2[1]4[3]2[1]5).
Below is the code which I have tried to use to make it work, but doing it as one slice only returns the single digit, whereas doing it as two means it returns the expected value. Why is this?
num = 512341234
str(num)[1::-2] #returns 1
str(num)[::-1][1::2] #returns 3131
Thanks!
Noah
1::-2 means to start at position 1 (the second character) and go backwards two characters at a time. You want to start somewhere near the end of the string, e.g.
num = 512341234
str(num)[-1::-2]
'42425'
num = 512341234
str(num)[-2::-2]
'3131'
But you’ll have to pick -1 or -2 based on which one of those characters is in an even position (i.e. based on the length of the string) to do this.
This question already has answers here:
Understanding slicing
(38 answers)
Closed 6 years ago.
I'm trying to understand the logic behind reversing a slice using slice index and step.
First of all, I can reverse a string using the slice step like this:
a = "Hello"
a[::-1]
>>> 'olleH'
Also, I can reverse only a part of the string like this:
a = "Hello"
a[:2:-1]
>>> 'ol'
But when I try to reverse the string using another range like this:
a = "Hello"
a[1:3:-1]
>>> ''
I get an empty string.
However, if I inverse the ranges like this example:
a = "Hello"
a[4:1:-1]
>>> 'oll'
I get the reversed slice between indexes 1 and 4.
But, correct me if I'm wrong, I know that the first index from a slice must be less than the second index.
This is why when I run this example:
a = "Hello"
a[4:1]
>>> ''
I get an empty string.
So, can somebody explain to me why reversing a string (slice) while an inversed range with a negative step works, and using the logic of the first index being less than the second one in a slice will give an empty string.
Thanks for your answers.
It is not the case that the first number has to be less than the second, it just is the starting index, while the second is the ending index. Therefore, when you are going backwards (third index is -1), the starting index should be larger than the ending index, otherwise you'll get an empty string.
The syntax is
a[begin;end;step]
So when you use step -1 it will traverse through the string backwards and thus begin should be bigger than the end.
If you omit step it defaults to 1 and will traverse through the string forward and should begin must be smaller than the end.
Fun fact, you can also traverse in steps of -2
a = 'Hello, world!'
a[::-2] # => '!lo olH'
This question already has answers here:
Understanding slicing
(38 answers)
Closed 4 years ago.
I cannot understand this. I have seen this in people's code. But cannot figure out what it does. This is in Python.
str(int(a[::-1]))
Assuming a is a string. The Slice notation in python has the syntax -
list[<start>:<stop>:<step>]
So, when you do a[::-1], it starts from the end towards the first taking each element. So it reverses a. This is applicable for lists/tuples as well.
Example -
>>> a = '1234'
>>> a[::-1]
'4321'
Then you convert it to int and then back to string (Though not sure why you do that) , that just gives you back the string.
The notation that is used in
a[::-1]
means that for a given string/list/tuple, you can slice the said object using the format
<object_name>[<start_index>, <stop_index>, <step>]
This means that the object is going to slice every "step" index from the given start index, till the stop index (excluding the stop index) and return it to you.
In case the start index or stop index is missing, it takes up the default value as the start index and stop index of the given string/list/tuple. If the step is left blank, then it takes the default value of 1 i.e it goes through each index.
So,
a = '1234'
print a[::2]
would print
13
Now the indexing here and also the step count, support negative numbers. So, if you give a -1 index, it translates to len(a)-1 index. And if you give -x as the step count, then it would step every x'th value from the start index, till the stop index in the reverse direction. For example
a = '1234'
print a[3:0:-1]
This would return
432
Note, that it doesn't return 4321 because, the stop index is not included.
Now in your case,
str(int(a[::-1]))
would just reverse a given integer, that is stored in a string, and then convert it back to a string
i.e "1234" -> "4321" -> 4321 -> "4321"
If what you are trying to do is just reverse the given string, then simply a[::-1] would work .
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.