Zeeran
Zeeran

Reputation: 173

How to shift a string to right in python?

I tried shifting a string to right

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))

Upvotes: 9

Views: 29468

Answers (11)

BGOPC
BGOPC

Reputation: 197

You can use .pop()

def shift(lst, side):
    if side == "left":
        a = lst.pop(0)
        return lst + [a]
    elif side == "right":
        a = lst.pop()
        return [a] + lst
    raise ValueError("Side is incorrect: " + side)

Upvotes: 1

Michele d'Amico
Michele d'Amico

Reputation: 23721

And now ...

Contest time

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:

  1. brute force: split all string
  2. take care that we need just the last part of the string

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 :)

Upvotes: 10

Shashank
Shashank

Reputation: 13869

Faster solution using str.rfind, string slice, and string concatenation:

>>> s = 'I Me You'
>>> lsi = s.rfind(' ')
>>> s[lsi+1:] + ' ' + s[:lsi]
'You I Me'

Another fast solution with str.rsplit:

>>> rs = s.rsplit(maxsplit=1)
>>> rs[1] + ' ' + rs[0]
'You I Me'

In function forms:

def find_and_slice(s):
    lsi = s.rfind(' ')
    return s[lsi+1:] + ' ' + s[:lsi]

def rs(s):
    rs = s.rsplit(maxsplit=1)
    return rs[1] + ' ' + rs[0]

Upvotes: 2

letsc
letsc

Reputation: 2567

My two cents:

string = 'this is a test string'
new_str = string.split() #The .split() method splits a string into a list
new_str[0],new_str[-1] = new_str[-1], new_str[0] #this is where python gets so amazing
print ' '.join(new_str) #just join the list again

Output

'string is a test this'

Upvotes: 0

myaut
myaut

Reputation: 11504

You may do that without using lists if all separators are same (split without parameters accepts all whitespace characters). Use string methods like rindex or rpartition:

 >>> part = s.rpartition(' ')
 >>> part[-1] + part[1] + part[0]
 'You I Me'

Upvotes: 2

pzp
pzp

Reputation: 6597

If you make the string a collections.deque, then you can use the rotate() method:

from collections import deque

s = 'I Me You'
s_deq = deque(s.split())
s_deq.rotate(1)
print ' '.join(s_deq)
#OUT: You I Me

Upvotes: 2

TigerhawkT3
TigerhawkT3

Reputation: 49318

def shift_right(sr):
    L = sr.split()
    return ' '.join([L[-1]]+L[:-1])

Upvotes: 0

Malik Brahimi
Malik Brahimi

Reputation: 16711

You can use indices and slices to create a new list which you then join by spaces:

print(' '.join([s.split()[-1]] + s.split()[:-1])) # You I Me

Upvotes: 1

Benjamin Rowell
Benjamin Rowell

Reputation: 1411

s = "I Me You"

In [2]: s.rsplit(None, 1)[-1] + ' ' + s.rsplit(None, 1)[0]
Out[3]: "You I Me"

Upvotes: 1

JuniorCompressor
JuniorCompressor

Reputation: 20015

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'

Upvotes: 6

Vladimir
Vladimir

Reputation: 348

This code will work for you

def shift_str(s):
    arr = s.split()
    first = arr.pop(0)
    arr.append(first)
    return " ".join(arr)

E.g:

shift_str("xxx ccc lklklk") >> 'ccc lklklk xxx'

Upvotes: 1

Related Questions