在不使用内置函数的情况下反转列表

时间:2016-09-15 04:01:08

标签: python list python-3.x

我使用的是Python 3.5。

作为问题的一部分,我试图设计一个将列表作为输入并将其还原的函数。因此,如果x = [a, b, c]该函数会生成x = [c, b, a]

问题是,我不允许使用任何内置功能,而且它让我陷入困境。我最初的想法是函数内的以下循环:

for revert in range(1, len(x) + 1):
    y.append(x[-revert])

它有效。但问题是我使用len(x),我相信这是一个内置函数,对吗?

所以我四处搜索并制作了以下非常简单的代码:

y = x[::-1]

这正是我想要的,但它似乎过于简单/容易,我不确定"::"是否算作一个功能。

所以我想知道是否有人有任何提示/想法如何手动设计所述功能?当你不能使用任何内置函数时,它似乎真的很难,现在我已经停留了很长时间。

8 个答案:

答案 0 :(得分:5)

rangelen都是built-in functions。由于接受了list 方法,您可以使用insert执行此操作。它 reeaallyy slow * 但是它在不使用任何内置函数的情况下完成列表的工作:

def rev(l):
    r = []
    for i in l:
        r.insert(0, i)
    return r

通过连续插入第零个位置,您最终得到了输入列表的反转版本:

>>> print(rev([1, 2, 3, 4]))
[4, 3, 2, 1]

这样做的:

def rev(l): 
    return l[::-1] 

也可以被认为是一种解决方案。 ::-1::有不同的结果)不是一个函数(它是一个切片)而[]也是一个列表方法。此外,对比insert,它更快,更可读;只要确保你能够理解并解释它。可以在 in this S.O answer.

找到关于其工作原理的一个很好的解释

* Reeaaalllyyyy缓慢,请参阅juanpa.arrivillaga对酷情节的回答和appendpop的回答,并查看列表上的就地reverse在Yoav Glazner的回答中完成。

答案 1 :(得分:1)

::不是函数,它是 python literal 。以及[]

如何检查::, []是否为函数。简单,

    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

如果::,[]是函数,则应在CALL_FUNCTION语句执行的python指令中找到标签a[::-1]。所以,他们不是。

看一下调用函数时python指令的样子,假设list()函数

>>> dis.dis(compile('list()', '', 'eval'))
  1           0 LOAD_NAME                0 (list)
              3 CALL_FUNCTION            0
              6 RETURN_VALUE

所以,基本上

def rev(f):
    return f[::-1]

工作正常。但是,我认为如果你的问题是家庭作业或由老师发送,你应该像Jim在答案中建议的那样做。但是,您可以添加这种最快捷的方式作为旁注。

如果老师抱怨[::-1]符号,请告诉他我给你的例子。

答案 2 :(得分:1)

这是一个不使用内置函数但依赖于list方法的解决方案。正如您的规范所暗示的那样,它就地反转:

>>> x = [1,2,3,4]
>>> def reverse(seq):
...   temp = []
...   while seq:
...     temp.append(seq.pop())
...   seq[:] = temp
... 
>>> reverse(x)
>>> x
[4, 3, 2, 1]
>>> 

ETA

吉姆,你在0号位置使用insert的答案让我疯了!那个解决方案是二次时间!您可以将appendpop与临时列表一起使用,以使用简单的列表方法实现线性时间。请参阅(reverse为蓝色,rev为绿色):

如果感觉有点像使用seq[:] = temp“作弊”,我们总是可以循环temp并将每个项目追加到seq,时间复杂度仍然是线性的,但可能由于它没有使用基于C的内部结构,因此速度较慢。

答案 3 :(得分:1)

另一种方式(仅为完整性:))

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

答案 4 :(得分:0)

您的示例有效:

y = x[::-1]

使用Python slices notation,这不是我假设您正在请求的意义上的函数。基本上::充当分隔符。您的代码的更详细版本将是:

y = x[len(x):None:-1]

y = x[start:end:step]

我可能不会抱怨python让你的生活真的非常轻松。

编辑超级迂腐。有人可能会说,调用[]根本就是使用内置的python函数,因为它实际上是方法__getitem__()的语法糖。

x.__getitem__(0) == x[0]

使用::确实会使用slice()对象。

x.__getitem__(slice(len(x), None, -1) == x[::-1]

但是......如果你要论证这一点,你在python中编写的任何内容都将使用内置的python函数。

答案 5 :(得分:0)

另一种完整性方法,<div class="sample-class" ng-if="abc"> some data 1 </div> <div class="sample-class" ng-if="!abc"> some data 2 </div> <div class="sample-class" ng-if="xyz"> some data 3 </div> <div class="sample-class" ng-if="abc"> some data 4 </div> <div class="sample-class" ng-if="!xyz"> some data 5 </div> <div>Total count is: {{getCount(); totalCount}}</div> <script type="text/javascript"> angular.module('app', []) .controller('ctrl', function($scope, $timeout) { $scope.totalCount = 0; $scope.getCount = function(){ $timeout(function(){ $scope.totalCount = document.getElementsByClassName('sample-class').length; }); }; }); </script> 采用可选步骤参数,允许您在列表中向后退一步:

range()

答案 6 :(得分:0)

实现这一目标的最pythonic和有效方法是通过列表切片。而且,既然你提到你不需要任何内置功能,它完全满足你的要求。例如:

>>> def reverse_list(list_obj):
...     return list_obj[::-1]
...
>>> reverse_list([1, 3, 5 , 3, 7])
[7, 3, 5, 3, 1]

答案 7 :(得分:0)

只需从右到左迭代列表即可获取项目..

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