我正在寻找一种优雅的方法来编写一个简单的函数,该函数将列表的元素移动给定数量的位置,同时保持相同长度的列表并用默认值填充空位置。这将是函数的文档字符串:
def shift_list(l, shift, empty=0):
"""
Shifts the elements of a list **l** of **shift** positions,
padding new items with **empty**::
>>> l = [0, 1, 4, 5, 7, 0]
>>> shift_list(l, 3)
[0, 0, 0, 0, 1, 4]
>>> shift_list(l, -3)
[5, 7, 0, 0, 0, 0]
>>> shift_list(l, -8)
[0, 0, 0, 0, 0, 0]
"""
pass
你会怎么做?任何帮助非常感谢!
答案 0 :(得分:3)
我使用切片分配:
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
答案 1 :(得分:2)
如果您可以使用deque而不是列表,它有一些很好的功能,使其成为此问题的自然选择。在双端队列左侧工作比在列表上这样做要便宜得多。它还有maxlen argument,可用于使代码更漂亮,更快。我相信使用itertools.repeat
而不是[empty] * n
更有效率,包括内存wize和速度。
from collections import deque
from itertools import repeat
def shift_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 performance
return d
虽然有点警告 - 虽然迭代双端队列元素的时间复杂度与列表中的相同,但是项目查找可能相当昂贵 - 这取决于在索引上:s[0]
和s[-1]
非常快,s[len(s)/2]
是最贵的。因此,如果您进行大量查找,请考虑使用其他解决方案,或将结果转换回列表。有关概述,请参阅this page。
答案 2 :(得分:1)
有点天真,但工作已经完成。
def shift(l, shift, empty=0):
reverse = False
if shift < 0:
reverse = True
shift = abs(shift)
while (shift > 0) :
if reverse:
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
答案 3 :(得分:1)
旋转列表的非直观方式
def shift_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))
答案 4 :(得分:0)
会这样做吗?
def shift_list(l, shift, empty=0):
while shift > 0:
l.insert(0,empty)
l.pop()
shift -= 1
return l
答案 5 :(得分:0)
我会这样做:
def shift_list(l, shift, empty=0):
if shift > 0:
return [empty] * shift + l[:-shift]
return l[-shift:] + [empty] * abs(shift)