[英]Reverse a list without using built-in functions
I'm using Python 3.5. 我正在使用Python 3.5。
As part of a problem, I'm trying to design a function that takes a list as input and reverts it. 作为问题的一部分,我正在尝试设计一个将列表作为输入并将其还原的函数。 So if x = [a, b, c]
the function would make x = [c, b, a]
. 因此,如果x = [a, b, c]
则函数将使x = [c, b, a]
。
The problem is, I'm not allowed to use any built-in functions, and it has got me stuck. 问题是,我不允许使用任何内置函数,它让我陷入困境。 My initial thought was the following loop inside a function: 我最初的想法是函数内的以下循环:
for revert in range(1, len(x) + 1):
y.append(x[-revert])
And it works. 它有效。 But the problem is I'm using len(x)
, which I believe is a built-in function, correct? 但问题是我使用len(x)
,我相信它是一个内置函数,对吗?
So I searched around and have made the following very simple code: 所以我四处搜索并制作了以下非常简单的代码:
y = x[::-1]
Which does exactly what I wanted, but it just seems almost too simple/easy and I'm not sure whether "::"
counts as a function. 这正是我想要的,但它看起来几乎太简单/容易,我不确定"::"
是否算作一个函数。
So I was wondering if anyone had any hints/ideas how to manually design said function? 所以我想知道是否有人有任何提示/想法如何手动设计所述功能? It just seems really hard when you can't use any built-in functions and it has me stuck for quite some time now. 当你不能使用任何内置函数时它看起来真的很难,现在我已经停留了很长时间。
range
and len
are both built-in functions . range
和len
都是内置函数 。 Since list
methods are accepted, you could do this with insert
. 由于接受了list
方法 ,您可以使用insert
执行此操作。 It is reeaallyy slow * but it does the job for small lists without using any built-ins: 它实际上很慢 *但是它可以在不使用任何内置函数的情况下完成小型列表的工作:
def rev(l):
r = []
for i in l:
r.insert(0, i)
return r
By continuously inserting at the zero-th position you end up with a reversed version of the input list: 通过连续插入第零个位置,您最终得到了输入列表的反转版本:
>>> print(rev([1, 2, 3, 4]))
[4, 3, 2, 1]
Doing: 这样做:
def rev(l):
return l[::-1]
could also be considered a solution. 也可以被认为是一种解决方案。 ::-1
( ::
has a different result) isn't a function (it's a slice) and []
is, again, a list method. ::-1
( ::
有不同的结果)不是一个函数(它是一个切片)而[]
是一个列表方法。 Also, contrasting insert
, it is faster and way more readable; 此外,对比insert
,它更快,更可读; just make sure you're able to understand and explain it. 只要确保你能够理解并解释它。 A nice explanation of how it works can be found in this SO answer. 在这个SO答案中可以找到关于它如何工作的一个很好的解释。
*Reeaaalllyyyy slow, see juanpa.arrivillaga's answer for cool plot and append
with pop
and take a look at in-place reverse
on lists as done in Yoav Glazner's answer. * Reeaaalllyyyy缓慢,看到juanpa.arrivillaga对于很酷的情节的回答,并append
pop
并在Yoav Glazner的回答中查看列表上的就地reverse
。
::
is not a function, it's a python literal . ::
不是函数,它是一个python文字 。 as well as []
以及[]
How to check if ::, []
are functions or not. 如何检查::, []
是否为函数。 Simple, 简单,
import dis
a = [1,2]
dis.dis(compile('a[::-1]', '', 'eval'))
1 0 LOAD_NAME 0 (a)
3 LOAD_CONST 0 (None)
6 LOAD_CONST 0 (None)
9 LOAD_CONST 2 (-1)
12 BUILD_SLICE 3
15 BINARY_SUBSCR
16 RETURN_VALUE
If ::,[]
were functions, you should find a label CALL_FUNCTION
among python instructions executed by a[::-1]
statement. 如果::,[]
是函数,则应在a[::-1]
语句执行的python指令中找到标签CALL_FUNCTION
。 So, they aren't. 所以,他们不是。
Look how python instructions looks like when you call a function, lets say list()
function 看一下调用函数时python指令的样子,比如说list()
函数
>>> dis.dis(compile('list()', '', 'eval'))
1 0 LOAD_NAME 0 (list)
3 CALL_FUNCTION 0
6 RETURN_VALUE
So, basically 所以,基本上
def rev(f):
return f[::-1]
works fine. 工作良好。 But, I think you should do something like Jim suggested in his answer if your question is a homework or sent by you teacher. 但是,我认为如果你的问题是家庭作业或由老师发送,你应该像Jim在答案中建议的那样做。 But, you can add this quickest way as a side note. 但是,您可以添加这种最快的方式作为旁注。
If you teacher complains about [::-1]
notation, show him the example I gave you. 如果老师抱怨[::-1]
符号,请告诉他我给你的例子。
Here's a solution that doesn't use built-in functions but relies on list methods. 这是一个不使用内置函数但依赖于list方法的解决方案。 It reverse in-place, as implied by your specification: 如您的规范所暗示的那样,它就地反转:
>>> x = [1,2,3,4]
>>> def reverse(seq):
... temp = []
... while seq:
... temp.append(seq.pop())
... seq[:] = temp
...
>>> reverse(x)
>>> x
[4, 3, 2, 1]
>>>
Jim, your answer using insert
at position 0 was driving me nuts! 吉姆,你在0号位置使用insert
的答案让我疯了! That solution is quadratic time! 那个解决方案是二次时间! You can use append
and pop
with a temporary list to achieve linear time using simple list methods. 您可以使用append
和pop
临时列表来使用简单的列表方法实现线性时间。 See ( reverse
is in blue, rev
is green): 请参阅( reverse
为蓝色, rev
为绿色):
If it feels a little bit like "cheating" using seq[:] = temp
, we could always loop over temp
and append every item into seq
and the time complexity would still be linear but probably slower since it isn't using the C-based internals. 如果感觉有点像使用seq[:] = temp
“作弊”,我们总是可以循环遍历temp
并将每个项目追加到seq
,时间复杂度仍然是线性的但可能更慢,因为它没有使用C-基于内部。
Another way ( just for completeness :) ) 另一种方式(仅为完整:))
def another_reverse(lst):
new_lst = lst.copy() # make a copy if you don't want to ruin lst...
new_lst.reverse() # notice! this will reverse it in place
return new_lst
Your example that works: 你的榜样有效:
y = x[::-1]
uses Python slices notation which is not a function in the sense that I assume you're requesting. 使用Python 切片表示法 ,这是我假设您正在请求的意义上的功能。 Essentially ::
acts as a separator. 基本上::
充当分隔符。 A more verbose version of your code would be: 更详细的代码版本是:
y = x[len(x):None:-1]
or 要么
y = x[start:end:step]
I probably wouldn't be complaining that python makes your life really, really easily. 我可能不会抱怨python让你的生活变得非常轻松。
Edit to be super pedantic. 编辑超级迂腐。 Someone could argue that calling []
at all is using an inbuilt python function because it's really syntactical sugar for the method __getitem__()
. 有人可能会说,调用[]
根本就是使用内置的python函数,因为它实际上是方法__getitem__()
语法糖。
x.__getitem__(0) == x[0]
And using ::
does make use of the slice()
object. 而使用::
确实使用了slice()
对象。
x.__getitem__(slice(len(x), None, -1) == x[::-1]
But... if you were to argue this, anything you write in python would be using inbuilt python functions. 但是......如果你要争论这个,你在python中编写的任何内容都将使用内置的python函数。
Another way for completeness, range()
takes an optional step parameter that will allow you to step backwards through the list: 另一种完整性方法, range()
采用可选的步骤参数,允许您在列表中向后退步:
def reverse_list(l):
return [l[i] for i in range(len(l)-1, -1, -1)]
The most pythonic and efficient way to achieve this is by list slicing. 实现这一目标的最pythonic和有效方法是通过列表切片。 And, since you mentioned you do not need any inbuilt function, it completely suffice your requirement. 而且,既然你提到你不需要任何内置功能,它完全满足你的要求。 For example: 例如:
>>> def reverse_list(list_obj):
... return list_obj[::-1]
...
>>> reverse_list([1, 3, 5 , 3, 7])
[7, 3, 5, 3, 1]
Just iterate the list from right to left to get the items.. 只需从右到左迭代列表即可获取项目..
a = [1,2,3,4]
def reverse_the_list(a):
reversed_list = []
for i in range(0, len(a)):
reversed_list.append(a[len(a) - i - 1])
return reversed_list
new_list = reverse_the_list(a)
print new_list
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.