String slicing returning unexpected values - python

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.

Related

Python strings slicing

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'

Python String Slicing: What is the semantic logic of the expression s[-1:-len(s)-1:-1] with arbitrary string s?

With arbitrary string s, s[::-1] inverts the string and is equivalent to s[-1:-len(s)-1:-1].
For example: with s = "abc" , s[::-1] and s[-1:-len(s)-1:-1] produce "cba".
I am wondering if anyone can explain the stop position of the latter expression -len(s)-1. I found nothing in the Python docs which elaborate on string slicing stop position syntax besides provided integer values and colons as default s[len(s)].
Negative indices are essentially operating on principles of modular arithmetic.
They wrap around to the end of the list. So s[-1] is the last character in the string, s[-2] is the second-to-last character in the string, ... all the way to s[-len(s)] is therefore the first character in the string.
Because we want to include the first character and slices don't include the "upper" bound, we use -len(s)-1 as the stopping point for the reversal. That is, the slice starts at -1 and increments by a further -1 each time, with the last index it includes being -len(s) which corresponds to the first character of the string.

How can I access a element from list if its in one number without comma?

example: [1233456]
How to access the fourth element? Basically I am taking input from the user, but when I print the length it shows me one and if I put a comma in between the numbers it shows correctly. So I want to access an element from a number as I ask before.
int(str(ex[0])[3])
The program takes the 1st element of the list(which in your case is '1233456'), converts it into a string(because integers are not subscriptable). Takes the fourth character of the string, which has an index of 3 as indexes in python start at 0.
And finally, converts it back to an integer.
I think this resource on Sequential Data Types might help you.
When you have [1233456] it's actually one single integer as the first element (0) in a list.
If you cast it to a string, you can pick out the individual characters, which you can then cast back to integers with int():
>>> my_ints = [1233456]
>>> my_str = str(my_ints[0])
>>> my_str[2]
'3'
>>> int(my_str[2])
3
Please remember [2] is the third element of the list, as they are zero-indexed... ;-)
Hope that helps!!!

Longest Subsequence problem if the lengths are different

Let the input sequences be X[0..m-1] and Y[0..n-1] of lengths m and n respectively. And let L(X[0..m-1], Y[0..n-1]) be the length of LCS of the two sequences X and Y. Following is the recursive definition of L(X[0..m-1], Y[0..n-1]).
If last characters of both sequences match (or X[m-1] == Y[n-1]) then
L(X[0..m-1], Y[0..n-1]) = 1 + L(X[0..m-2], Y[0..n-2])
If last characters of both sequences do not match (or X[m-1] != Y[n-1]) then
L(X[0..m-1], Y[0..n-1]) = MAX ( L(X[0..m-2], Y[0..n-1]), L(X[0..m-1], Y[0..n-2]) )
How to solve the problem if the lengths are different ? and how to print the respective sequences
It doesn't matter if the length of input strings are same or not, and this is taken care by the base case of recursion.
if (m == 0 || n == 0)
return 0;
If we reach the end of any one of the string, the recursion stops and unwinds from there.
Also the example you mentioned in comment:
ABCEFG and ABXDE
First we compare last character from both string. In this case, they are not same.
So we try two cases:
Remove last character from first string and compare it with second.
Remove last character from second string and compare it with first.
And return the max from both cases.
(As a side note, if the last character had matched, we would add 1 to our answer and remove the last character from both strings)
This process continues till any of the string reaches it's end, in which case, the base case of your recursion is satisfied and the recursion returns.
So it doesn't matter if the original length of string is same or not.

find() function in python2.7.5

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.

Categories