patternpythonMinor
Shift elements left by n indices in a list
Viewed 0 times
shiftleftindiceselementslist
Problem
For the following question, the function
• should mutate the original list
• should NOT create any new lists
• should NOT return anything
Functions that do not create new lists are said to be ”in place.” Such functions are often desirable because they do not require extra memory to operate.
Define shift_left, a function that takes a list and shifts each element in the list to the left by n indices. If elements start ”falling off” on the left, they are placed back on the right. NOTE: you may assume that n is a non-negative integer.
Below is the solution:
I have yet to learn about raising exceptions in Python.
Can this code be more elegant by following a recursive approach? As of now, space (stack frame) usage can be considered secondary.
• should mutate the original list
• should NOT create any new lists
• should NOT return anything
Functions that do not create new lists are said to be ”in place.” Such functions are often desirable because they do not require extra memory to operate.
Define shift_left, a function that takes a list and shifts each element in the list to the left by n indices. If elements start ”falling off” on the left, they are placed back on the right. NOTE: you may assume that n is a non-negative integer.
def shift_left(lst, n):
"""Shifts the elements of lst over by n indices.
>>> lst = [1, 2, 3, 4, 5]
>>> shift_left(lst, 2)
>>> lst
[3, 4, 5, 1, 2]
"""Below is the solution:
def shift_left(lst, n):
"""Shifts the lst over by n indices
>>> lst = [1, 2, 3, 4, 5]
>>> shift_left(lst, 2)
>>> lst
[3, 4, 5, 1, 2]
"""
assert (n > 0), "n should be non-negative integer"
def shift(ntimes):
if ntimes == 0:
return
else:
temp = lst[0]
for index in range(len(lst) - 1):
lst[index] = lst[index + 1]
lst[index + 1] = temp
return shift(ntimes-1)
return shift(n)I have yet to learn about raising exceptions in Python.
Can this code be more elegant by following a recursive approach? As of now, space (stack frame) usage can be considered secondary.
Solution
Some suggestions:
-
The assignment says “ you may assume that n is a non-negative integer”, but the condition you check is “n > 0”. Since n = 0 is non-negative (and corresponds to no mutation of the list), you should handle that as well.
-
An assert should only really be used to check that the program isn’t in an impossible situation. It would be preferable to use exceptions, and it’s very simple to do so:
(Alternatively, you could implement negative indices as right-shifting, but I’ll leave that for now.)
-
You can condense the for loop in
Everything except the last element in
You can extend this list slicing to do away with the
-
At that point, the
-
The assignment says “ you may assume that n is a non-negative integer”, but the condition you check is “n > 0”. Since n = 0 is non-negative (and corresponds to no mutation of the list), you should handle that as well.
-
An assert should only really be used to check that the program isn’t in an impossible situation. It would be preferable to use exceptions, and it’s very simple to do so:
if n < 0:
raise ValueError("Input %d is not a non-negative integer" % n)(Alternatively, you could implement negative indices as right-shifting, but I’ll leave that for now.)
-
You can condense the for loop in
shift with a list slice: the following code achieves the same effect:lst[:-1] = lst[1:]Everything except the last element in
lst is assigned to the element one to its left in the original list.You can extend this list slicing to do away with the
temp variable (which is probably a bit more memory efficient), and do the list slicing in a single line. Shifting one position to the left is achieved with the linelst[:] = lst[1:] + [lst[0]]-
At that point, the
shift() function is almost so simple that you can do away with it entirely, and recurse only on the shift_left() function. Here’s what I reduced it to:if n == 0:
return
else:
lst[:] = lst[1:] + [lst[0]]
shift_left(lst, n-1)Code Snippets
if n < 0:
raise ValueError("Input %d is not a non-negative integer" % n)lst[:-1] = lst[1:]lst[:] = lst[1:] + [lst[0]]if n == 0:
return
else:
lst[:] = lst[1:] + [lst[0]]
shift_left(lst, n-1)Context
StackExchange Code Review Q#88684, answer score: 7
Revisions (0)
No revisions yet.