Skip to content Skip to sidebar Skip to footer

Python: Shift Elements In A List With Constant Length

I'm looking for an elegant way to write a simple function that would shift the elements of list by a given number of positions, while keeping the list of the same length and paddin

Solution 1:

I'd use slice assignment:

def shift_list(l, shift, empty=0):
    src_index = max(-shift, 0)
    dst_index = max(shift, 0)
    length = max(len(l) - abs(shift), 0)
    new_l = [empty] * len(l)
    new_l[dst_index:dst_index + length] = l[src_index:src_index + length]
    return new_l

Solution 2:

If you can use a deque instead of a list, it has a few nice features that make it a natural choice for this problem. Working from the left of a deque is much less expensive than doing so on a list. Also it has a maxlen argument that can be used to make the code prettier and faster. I'm rather sure using itertools.repeat instead of [empty] * n is more efficient, both memory-wize and with regards to speed.

from collections import deque
from itertools import repeat

defshift_list(l, n, empty=0):
    d = deque(l, maxlen=len(l))
    if n > 0:
        d.extendleft(repeat(empty, min(n, len(l))))
    elif n < 0:
        d.extend(repeat(empty, min(-n, len(l))))
    # return list(d) to pass your doctest, at the cost of performancereturn d   

A bit of a warning though -- while the time complexity of iterating over the elements of a deque is comparable to doing the same on a list, item lookup may be rather expensive -- it depends on the index: s[0] and s[-1] is very fast, s[len(s)/2] is the most expensive. So if you do a lot of lookups, consider either using another solution, or converting the result back to a list. See this page for an overview.

Solution 3:

A bit naïve, but job's done.

def shift(l, shift, empty=0):
    reverse = False
    ifshift < 0:
        reverse = True
        shift = abs(shift)
    while (shift > 0) :
        ifreverse:
            l.pop(0)
            l.append(empty)
        else:
            l.pop()
            l.insert(0, empty)
        shift-=1



l = [0, 1, 4, 5, 7, 0]
shift(l, 3)
print l
l = [0, 1, 4, 5, 7, 0]
shift(l, -3)
print l
l = [0, 1, 4, 5, 7, 0]
shift(l, -8)
print l

Solution 4:

A non intuitive way of rotating a list

defshift_list(l, shift, empty=0):
    l1=[empty]*len(l)+l+[empty]*len(l)
    l1=l1[len(l)-shift:][0:len(l)]
    return l1+[empty]*(len(l)-len(l1))

Solution 5:

I would do it like this:

def shift_list(l, shift, empty=0):
    ifshift > 0:
        return [empty] * shift + l[:-shift]

    return l[-shift:] + [empty] * abs(shift)

Post a Comment for "Python: Shift Elements In A List With Constant Length"