这是一个非常简单的问题,但我似乎无法找到令人满意的答案。
在Python中,最好的方法是使列表的最后一项成为第一个“推动”列表其余部分的项目。
做的事情:
>>> a=[1,2,3,4]
>>> a[?????]
[4, 1, 2, 3]
我知道我总是可以玩len
,列出串联......
>>> a=[1,2,3,4]
>>> [a[len(a)-1]] + a[0:len(a)-1]
[4, 1, 2, 3]
但这看起来不正确......“ Pythonic ”,如果你可以
提前谢谢。
答案 0 :(得分:12)
切片比这更聪明;您可以使用否定索引从最后开始计算:
a[-1:] + a[:-1]
演示:
>>> a=[1,2,3,4]
>>> a[-1:] + a[:-1]
[4, 1, 2, 3]
这适用于要移动到前面的任意数量的元素:
>>> a[-2:] + a[:-2]
[3, 4, 1, 2]
使用像这样的切片与使用.insert()
+ .pop()
(在短名单上)的速度相当:
>>> timeit.timeit('a[-1:] + a[:-1]', 'a=[1,2,3,4]')
0.59950494766235352
>>> timeit.timeit('a.insert(0,a.pop(-1))', 'a=[1,2,3,4]')
0.52790379524230957
但如果您需要移动多个元素,请赢得支持:
>>> timeit.timeit('a[-2:] + a[:-2]', 'a=[1,2,3,4]')
0.58687901496887207
>>> timeit.timeit('a.insert(0,a.pop(-1));a.insert(0,a.pop(-1))', 'a=[1,2,3,4]')
1.0615170001983643
答案 1 :(得分:8)
In [103]: a=[1,2,3,4]
In [104]: a.insert(0,a.pop(-1)) # pop(-1) removes the last element
# and use insert() to insert the popped
# element at 0th endex
In [105]: a
Out[105]: [4, 1, 2, 3]
答案 2 :(得分:8)
你可能想看一下deque,如果你做了很多这些,那就是优化(记忆明智)来做你所要求的。
from collections import deque
>>> a = deque([1,2,3,4])
>>> a.rotate(1)
... deque([4, 1, 2, 3])
因为我们正在进行timeit
比较......
>>> setup = """from collections import deque
a = deque([1,2,3,4])"""
>>> print timeit.timeit('a.rotate(1)', setup=setup)
... 0.219103839131
答案 3 :(得分:0)
如果您只需要转储任意访问的列表,正如您在@kreativitea的评论中所提到的那样,甚至可能不需要重新排序,您可以设计一个任意的访问生成器:
size = 10
l = range(size)
# use a generator expression to yield slices of the list according
# to your own order.
# note that no error checking is enforced, and that overlapping
# and invalid accessRanges will work, so depending on the usage
# you have for this function, you might want to add some
# sanity checks, like ensuring no overlap between accessRanges
# and that each item is accessed only once.
def ArbitraryListAccessor(listObj, accessRanges):
for ar in accessRanges:
for item in listObj[ar[0]:ar[1]]:
yield item
# to dump the access-ordered list generator as a real list, you need to
# iterate over it, for example, with a list comprehension:
[i for i in ArbitraryListAccessor(l, ((-1,None), (0,-1)))]
# [9, 0, 1, 2, 3, 4, 5, 6, 7, 8]
它比deque慢,但比创建新列表更快。对于多次迭代,它的速度大约是deque的两倍,但对于单次运行(例如,只需按任意顺序读取一次列表),它就是可比较的(例如,微秒级)。
这里的好处是您可以定义要使用的任何随机访问范围。您还可以使用Slice
对象替换函数中的范围,并将其实现为常规列表切片(但是您已经提供了切片元组或切片对象。)