I tried shifting a string to right
s= "I Me You"
should return "You I Me"
I tried the following code but it doesn't work please help me out..
sr= "I Me You"
def shift_right(sr):
L=sr.split()
new_list=L[-1]
new_list= new_list.append(1,L[:0])
return (new_list)
print(shift_right(sr)
print (shift_reverse(sr))
strs[(strs. index(i) + shift) % 26] : line above means find the index of the character i in strs and then add the shift value to it. Now, on the final value(index+shift) apply %26 to the get the shifted index. This shifted index when passed to strs[new_index] yields the desired shifted character.
The 'r' at the start of the pattern string designates a python "raw" string which passes through backslashes without change which is very handy for regular expressions (Java needs this feature badly!).
The new line character in Python is \n . It is used to indicate the end of a line of text.
And now ...
Maybe what is more interesting is what is the faster approach?.
First test by the OP test string (just 3 chunks) and the second test by a string of 600 one char chunks.
from collections import deque
import timeit
def trivial(s):
l = s.split()
return ' '.join(l[-1:] + l[:-1])
def more_split(s):
return ' '.join([s.split()[-1]] + s.split()[:-1])
def dq(s):
s_deq = deque(s.split())
s_deq.rotate(1)
return ' '.join(s_deq)
def find_and_slice(s):
lsi = s.rfind(' ')
return s[lsi+1:] + ' ' + s[:lsi]
def rs_lazy(s):
return ' '.join(reversed(s.rsplit(maxsplit=1)))
def rs_smart(s):
rs = s.rsplit(maxsplit=1)
return rs[1] + ' ' + rs[0]
def rpart(s):
part = s.rpartition(' ')
return part[-1] + part[1] + part[0]
def time_a_method(m, s):
c_arg = "('{}')".format(s)
t = timeit.timeit(m + c_arg, setup="from __main__ import " + m , number=100000)
print( m + " "*(15-len(m)) + "----> {}".format(t))
if __name__ == '__main__':
print(trivial("I Me You"))
print(more_split("I Me You"))
print(dq("I Me You"))
print(find_and_slice("I Me You"))
print(rs_lazy("I Me You"))
print(rs_smart("I Me You"))
print(rpart("I Me You"))
print("######## USE: 'I Me You'")
for m in ["trivial", "more_split", "dq", "find_and_slice", "rs_lazy", "rs_smart", "rpart"]:
time_a_method(m, "I Me You")
print("######## USE: 'a b c d e f '*100")
s = 'a b c d e f '*100
for m in ["trivial", "more_split", "dq", "find_and_slice", "rs_lazy", "rs_smart", "rpart"]:
time_a_method(m, s)
That give follow results:
You I Me You I Me You I Me You I Me You I Me You I Me You I Me ######## USE: 'I Me You' trivial ----> 0.1339518820000194 more_split ----> 0.1532761280000159 dq ----> 0.182199565000019 find_and_slice ----> 0.07563322400005745 rs_lazy ----> 0.23457759100006115 rs_smart ----> 0.1615759960000105 rpart ----> 0.06102836100001241 ######## USE: 'a b c d e f '*100 trivial ----> 3.2239098259999537 more_split ----> 4.6946649449999995 dq ----> 3.991058845999987 find_and_slice ----> 0.15106809200005955 rs_lazy ----> 0.32278001499992115 rs_smart ----> 0.22939544400003342 rpart ----> 0.10590313199998036
And the winner is.....
def rpart(s):
part = s.rpartition(' ')
return part[-1] + part[1] + part[0]
That surprised me (I bet on find_and_slice
and I lost). There are 2 answers classes:
Even in the simplest case I Me You
the first approach is from 2 to 3 time slower than the best one. Obviously when the string become more interesting the first approach become really inefficient.
The real funny thing is that the most voted answer is the slower :)
First we split the string:
>>> s = "I Me You"
>>> l = s.split()
>>> l
['I', 'Me', 'You']
Then we add l[-1:]
, which is the list from the last element to the end, with l[:-1]
, which is the list from the start until (but not containing) the last element:
>>> l[-1:] + l[:-1]
['You', 'I', 'Me']
Finally we join:
>>> ' '.join(l[-1:] + l[:-1])
'You I Me'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With