通过迭代反转列表

时间:2013-12-02 14:19:23

标签: python

我想进入Python。在这里,我试图通过递归迭代来反转列表。 我听说过强大的切片功能,但我认为没有机会在这里使用它们:

def turn(l):
    skip = 0;
    while(skip < len(l)):
        if(l[skip] < l[skip+1]):
            break
        skip +=1
    t = l[len(l)-1]
    t2 = l[skip]
    l[skip] = t
    l[len(l)-1] = t2

    turn(l) 
    return 0

l = range(0,5)
print turn(l)

您在上面看到的代码是当前的实验状态。 但是我怎么能完成这个功能呢?

6 个答案:

答案 0 :(得分:5)

如果你真的需要自己和递归地做,那么:

def reverse(lst):
    if len(lst) < 2:
        return lst
    else:
        return [lst[-1]] + reverse(lst[:-1])

答案 1 :(得分:3)

这是切片选项

my_list[::-1]

很抱歉懒得分析你的代码,但是如果你真的想要反转列表顺序 - 你必须在到达列表中间时停止。 这是我的解决方案

In [155]: def turn(trgt, offs=0):
    if offs>=len(trgt)/2:
        return
    trgt[offs], trgt[-1-offs] = trgt[-1-offs], trgt[offs]
    turn(trgt, offs+1)
   .....:     

In [156]: 

In [156]: my_list=range(10)

In [157]: turn(my_list)

In [158]: my_list
Out[158]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

答案 2 :(得分:3)

您可以通过每次将列表拆分为一半来减少堆栈的最大深度,而不是一次拉出一个项目

def rev(L):
    if len(L) < 2:
        return L
    return rev(L[len(L) // 2:]) + rev(L[:len(L) // 2])

答案 3 :(得分:0)

使用

my_list.reverse()

它更容易。 python中的内置函数

答案 4 :(得分:0)

解决方案来了:

def dreh(list):
    v = list[0] 

    if len(list) > 1: 
        del list[0] 
        dreh(list) 
    else: 
        del list[0] 

    list.append(v)  
    return list

l = range(0,5)
l = dreh(l)
print l

但我必须承认,使用python的包含方法更方便:)

答案 5 :(得分:0)

我写过这段代码:

li = [0,1,3,5,9,12,14,25,'AAQ',32,54]
print 'li ==',li,'\nid(li) ==',id(li)

def rev(li):
    return [li.pop(-1)]  + rev(li) if li else li

lu =  rev(li)
print 'lu ==',lu,'\nid(lu) ==',id(lu)
print 'li==',li

结果

li == [0, 1, 3, 5, 9, 12, 14, 25, 'AAQ', 32, 54] 
id(li) == 18709560
lu == [54, 32, 'AAQ', 25, 14, 12, 9, 5, 3, 1, 0] 
id(lu) == 18736432
li== []

函数id()给出了对象内存中的地址 地址18709680和18736472不同,这意味着两个标识符lilu是位于存储器中不同位置的两个不同列表对象的引用。
这也意味着列表对象 li 没有被反转到位 此外,执行后列表 li 为空。

所以我想知道这些后果是否适合你。

然后我在你的回答帖中看到了你的解决方案,我看到它有同样的后果,所以你不用担心它们。

盯着你的代码,我乍看之下并没有很好地理解,我意识到它有一个类似我的算法,虽然反转(!)
我将在演示代码演变的帮助下解释以下内容。

请注意,我将标识list替换为LIST,因为list是内置类的名称,建议避免覆盖内置标识符。

首先,您的代码是:

def dreh(LIST):
    v = LIST[0] 

    if len(LIST) > 1: 
        del LIST[0] 
        dreh(LIST) 
    else: 
        del LIST[0] 

    LIST.append(v)  
    return LIST

仔细检查下面的代码,你会很容易理解它和你的代码一样,尽管它与你的相反(!)

def dreh(LIST):
    v = LIST[-1] 

    if len(LIST) > 1: 
        del LIST[-1] 
        dreh(LIST) 
    else: 
        del LIST[-1] 

    LIST.insert(0,v)  
    return LIST

在您的代码中,列表的第一个元素将被删除并保存在名称为v的对象中,剩余的列表将再次使用dreh()处理(结果为该标识符LIST然后引用一个新列表,其值为初始 LIST 对象的反转值,并且 v 的保留值为附加对这个新的反向LIST。

在我的代码中,我做了相反的事情:
li.pop(-1)删除列表中的 last 元素,将其单独放在列表中,扩展此长度为1的列表,其中列表由递归函数调用缩短的清单。


现在,我将证明这个反向代码在算法上与我自己的代码相同 但在此之前,有点精确 如果将一个void列表传递给函数dreh(),则会产生错误,因为它将首先尝试删除void列表中的第一个元素(或反转代码中的最后一个元素)。
然后你的代码必须稍微修改以保持这种情况,然后是:

def dreh(LIST):
    if len(LIST)>=1:
        v = LIST[-1] 

    if len(LIST) > 1: 
        del LIST[-1] 
        dreh(LIST) 
    elif len(LIST)==1: 
        del LIST[-1] 

    LIST.insert(0,v)  
    return LIST


现在这个代码的演变导致我的。我认为大多数步骤都很容易理解。最棘手的步骤是从结果la05到结果la06的步骤:必须仔细考虑并仔细了解Python中的分配中隐含的过程以理解这一部分。对不起,我不能写出解释这一步所需的所有东西,这太长了。无论如何,结果的显示表明代码的演变始终保持相同的结果。

li = [0,1,3,5,9,'AAAA',12,14,25,32,105,205]
print 'li  ==',li

def dreh(LIST):
    if len(LIST)>=1:
        v = LIST[-1] 

    if len(LIST) > 1: 
        del LIST[-1] 
        dreh(LIST) 
    elif len(LIST)==1: 
        del LIST[-1] 

    LIST.insert(0,v)  
    return LIST

li = [0,1,3,5,9,'AAAA',12,14,25,32,105,205]
la = dreh(li)
print 'la01==',la

def dreh(LIST):
    #if len(LIST)>=1:
    #    v = LIST[-1]

    if len(LIST) > 1:
        v = LIST[-1] # <======
        del LIST[-1] 
        dreh(LIST)
        LIST.insert(0,v) # <======
    elif len(LIST)==1:
        v = LIST[-1] # <======
        del LIST[-1]
        LIST.insert(0,v) # <======

    #if len(LIST)>=1:
    #    LIST.insert(0,v)
    return LIST

li = [0,1,3,5,9,'AAAA',12,14,25,32,105,205]
la = dreh(li)
print 'la02==',la

def dreh(LIST):
    if len(LIST) > 1:
        v = LIST[-1]
        del LIST[-1] 
        dreh(LIST)
        LIST.insert(0,v)
    elif len(LIST)==1:
        v = LIST[-1]
        del LIST[-1]
        LIST.insert(0,v)

    return LIST

li = [0,1,3,5,9,'AAAA',12,14,25,32,105,205]
la = dreh(li)
print 'la03==',la

def dreh(LIST):
    if len(LIST) > 1:
        #v = LIST[-1]
        #del LIST[-1]
        v = LIST.pop(-1) # <======
        dreh(LIST)
        LIST.insert(0,v)
    elif len(LIST)==1:
        #v = LIST[-1]
        #del LIST[-1]
        v = LIST.pop(-1) # <======
        LIST.insert(0,v)

    return LIST

li = [0,1,3,5,9,'AAAA',12,14,25,32,105,205]
la = dreh(li)
print 'la04==',la

def dreh(LIST):
    if len(LIST) > 1:
        v = LIST.pop(-1)
        dreh(LIST)
        LIST.insert(0,v)
    elif len(LIST)==1:
        v = LIST.pop(-1)
        LIST.insert(0,v)

    return LIST

li = [0,1,3,5,9,'AAAA',12,14,25,32,105,205]
la = dreh(li)
print 'la05==',la

def dreh(LIST):
    if len(LIST) > 1:
        LIST[:] = [LIST.pop(-1)] + dreh(LIST)
    elif len(LIST)==1:
        LIST[:] = [LIST.pop(-1)]

    return LIST

li = [0,1,3,5,9,'AAAA',12,14,25,32,105,205]
la = dreh(li)
print 'la06==',la

def dreh(LIST):
    if len(LIST) > 1:
        LIST[:] = [LIST.pop(-1)] + dreh(LIST)
        return LIST
    elif len(LIST)==1:
        LIST[:] = [LIST.pop(-1)]
        return LIST

li = [0,1,3,5,9,'AAAA',12,14,25,32,105,205]
la = dreh(li)
print 'la07==',la

def dreh(LIST):
    if len(LIST) > 1:
        return [LIST.pop(-1)] + dreh(LIST)
    elif len(LIST)==1:
        return [LIST.pop(-1)]

li = [0,1,3,5,9,'AAAA',12,14,25,32,105,205]
la = dreh(li)
print 'la08==',la

def dreh(LIST):
    if len(LIST) > 1:
        return [LIST.pop(-1)] + dreh(LIST)
    elif len(LIST)==1:
        return [LIST.pop(-1)] + []

li = [0,1,3,5,9,'AAAA',12,14,25,32,105,205]
la = dreh(li)
print 'la09==',la

def dreh(LIST):
    if len(LIST) > 1:
        return [LIST.pop(-1)] + dreh(LIST)
    elif len(LIST)==1:
        return [LIST.pop(-1)] + []
    elif len(LIST)==0:
        return []

li = [0,1,3,5,9,'AAAA',12,14,25,32,105,205]
la = dreh(li)
print 'la10==',la

def dreh(LIST):
    if len(LIST) > 1:
        return [LIST.pop(-1)] + dreh(LIST)
    elif len(LIST)==1:
        return [LIST.pop(-1)] + []
    elif len(LIST)==0:
        return LIST

li = [0,1,3,5,9,'AAAA',12,14,25,32,105,205]
la = dreh(li)
print 'la11==',la

def dreh(LIST):
    if len(LIST) > 1:
        return [LIST.pop(-1)] + dreh(LIST)
    elif len(LIST)==1:
        return [LIST.pop(-1)] + dreh(LIST)
    elif len(LIST)==0:
        return LIST

li = [0,1,3,5,9,'AAAA',12,14,25,32,105,205]
la = dreh(li)
print 'la12==',la

def dreh(LIST):
    if len(LIST) >= 1:
        return [LIST.pop(-1)] + dreh(LIST)
    elif len(LIST)==0:
        return LIST

li = [0,1,3,5,9,'AAAA',12,14,25,32,105,205]
la = dreh(li)
print 'la13==',la

def dreh(LIST):
    if LIST:
        return [LIST.pop(-1)] + dreh(LIST)
    else:
        return LIST

li = [0,1,3,5,9,'AAAA',12,14,25,32,105,205]
la = dreh(li)
print 'la14==',la

结果

li  == [0, 1, 3, 5, 9, 'AAAA', 12, 14, 25, 32, 105, 205]
la01== [205, 105, 32, 25, 14, 12, 'AAAA', 9, 5, 3, 1, 0]
la02== [205, 105, 32, 25, 14, 12, 'AAAA', 9, 5, 3, 1, 0]
la03== [205, 105, 32, 25, 14, 12, 'AAAA', 9, 5, 3, 1, 0]
la04== [205, 105, 32, 25, 14, 12, 'AAAA', 9, 5, 3, 1, 0]
la05== [205, 105, 32, 25, 14, 12, 'AAAA', 9, 5, 3, 1, 0]
la06== [205, 105, 32, 25, 14, 12, 'AAAA', 9, 5, 3, 1, 0]
la07== [205, 105, 32, 25, 14, 12, 'AAAA', 9, 5, 3, 1, 0]
la08== [205, 105, 32, 25, 14, 12, 'AAAA', 9, 5, 3, 1, 0]
la09== [205, 105, 32, 25, 14, 12, 'AAAA', 9, 5, 3, 1, 0]
la10== [205, 105, 32, 25, 14, 12, 'AAAA', 9, 5, 3, 1, 0]
la11== [205, 105, 32, 25, 14, 12, 'AAAA', 9, 5, 3, 1, 0]
la12== [205, 105, 32, 25, 14, 12, 'AAAA', 9, 5, 3, 1, 0]
la13== [205, 105, 32, 25, 14, 12, 'AAAA', 9, 5, 3, 1, 0]
la14== [205, 105, 32, 25, 14, 12, 'AAAA', 9, 5, 3, 1, 0]

我发现这个例子很有趣,因为它表明Python提供了很容易修改代码:
1 /它的可读性允许了解可以进行哪些修改 2 /它是一个紧凑的语言,易于重写,可以快速修改它。

我不知道如何像使用C ++一样轻松完成同样的工作。