Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:使数组的最后一项成为第一项_Python_List - Fatal编程技术网

Python:使数组的最后一项成为第一项

Python:使数组的最后一项成为第一项,python,list,Python,List,这是一个非常简单的问题,但我似乎还没有找到一个令人满意的答案 在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] 但这看起来不对。。。“P

这是一个非常简单的问题,但我似乎还没有找到一个令人满意的答案

在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”,如果可以的话


提前谢谢你。

切片比这要聪明一点;您可以使用负索引从末尾开始计数:

a[-1:] + a[:-1]
演示:

这适用于将任意数量的图元移动到前面:

>>> a[-2:] + a[:-2]
[3, 4, 1, 2]
像这样使用切片在速度上与使用
.insert()
+
.pop()
(在短列表中)相当:

但如果您需要移动多个元素,则可以轻松获胜:

>>> 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
如果你做了很多这样的事情,你可能会想看看哪些是经过优化的(内存方面的)来满足你的要求的

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

如果您只需要转储一个任意访问的列表,正如您在@krativitea的评论中提到的,甚至可能不需要重新排序,您可以设计一个任意访问生成器:

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的两倍,但是对于一次运行(例如,仅以任意顺序读取列表一次),它是可比较的(例如,微秒级)


这里的好处是,您可以定义任何想要使用的随机访问范围。您还可以将函数中的范围替换为
切片
对象,并将其实现为常规列表切片(但随后您提供了切片元组或切片对象)。

它仍然会创建一个新列表(实际上是三个列表),其中不应该创建任何列表。@delnan:为什么不应该创建任何列表?因为它不需要,这样做会毫无理由地增加几个列表遍历。。。对于较小的列表,它显然不会影响性能。。。对于巨大的列表,它可能有点…@delnan当使用常规列表时,这个操作不可能在少于O(n)的时间内完成。我已经使用了deque几次,现在我没有想到这一点,因为我有一个存储为[1,2,3,4]的列表,需要作为[4,1,2,3]输出(实际上在网页上)。记忆不是问题。。。我对速度更感兴趣。我认为将列表转换为deque,然后旋转它比切片更耗时。你怎么认为?(我不知道deque的性能)@BorrajaX我添加了性能信息。Deque的速度明显更快。Arg。。。我担心在这种特殊情况下,这不是一个选项,因为rotate(1)不会返回deque,所有这些过程都是在一个生成html的模板中完成的(因此它只需要一行代码)。非常感谢您的提示,尽管您只需要执行一次旋转,实例化deque有一点开销,这使得它比切片列表要慢。我打算建议创建一个返回deque的函数,并在一行程序中使用它,但从性能上看,列表切片似乎会更好地为您服务。@BorrajaX如果您只需要显示旋转的列表,为什么不使用一个函数来吐出给定任意顺序的项呢?
from collections import deque

>>> a = deque([1,2,3,4])
>>> a.rotate(1)
... deque([4, 1, 2, 3])
>>> setup = """from collections import deque
               a = deque([1,2,3,4])"""
>>> print timeit.timeit('a.rotate(1)', setup=setup)
... 0.219103839131
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]