需要替代Python列表反向解决方案

时间:2015-02-06 15:59:18

标签: python list reverse

我今天接受了面试。在此期间,我被要求写下一个反转列表的算法。首先,我使用reverse()方法提供了答案:

    x = [1,2,3,4,5]
    y = reversed(x)
    for i in y:
        print i

进行面试的高级开发人员问我是否知道另一种方式,在此基础上我用切片写下了另一种已知的方法:

   x = [1,2,3,4,5]
   y = x[::-1]

不幸的是,他对这个解决方案也不满意,并让我想到另一个。几分钟后,我说我无法想出更好的一个。他说这对他们的标准来说还不够好。

我对他的意见完全没问题,在我的代码上练习更多没有问题。我的问题是,如果有的话,我不知道什么是更好的解决方案。可能还有其他更多的“程序员”方式......只有其他想到的事情才是递归,但我只是在面试结束后才想到它。 感谢。

7 个答案:

答案 0 :(得分:4)

你的答案在python方面都很好,所以面试官一定要求你实现自己的方法:

使用递归:

def recur_rev(l):
    return recur_rev(l[1:]) + l[:1] if l else l

或者列表comp和范围从l -1的长度开始并反向运行:

l = list(range(100))

print([l[ind] for ind in range(len(l)-1,-1,-1)])

使用itertools.count:

from itertools import count
cn = count(len(l) -1, -1)

print([l[next(cn)] for ele in l])

为了提高效率,请使用生成器表达式:

rev  = (l[next(cn)] for ele in l)

for ele in rev:
    print(ele)

或使用地图:

print(list(map(l.__getitem__,range(len(l)-1,-1,-1)))) # list needed for python3

[99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

没有地图上的列表调用我们将得到一个我们可以在python3中迭代的地图对象,你可以在python2中使用itertools.imap来实现类似的结果

答案 1 :(得分:3)

我猜你的面试官想听到这样的话:

恢复列表的一种简单方法是找出它的长度,然后从len-1 downto 0迭代并将第i个元素追加到结果中。这种方法适用于真实列表,但是我们如何还原生成器,即长度未知且无法找到的东西? (好的pythonistas使用生成器和产量而不是列表和返回)。

我们需要一个名为" stack"的数据结构。堆栈就像是一堆东西,比如板子,放在彼此的顶部。

无论你把最后放在哪里首先出现首先出现的出现最后。所以,我们的策略将是这样的:

  • 虽然有项目,但将每个项目放入堆栈
  • 当堆栈不为空时,从堆栈中弹出项目并将其返回

可以使用列表在python中编写堆栈,其中.append将项目放在堆栈的顶部,.pop从堆栈中移除最后一件事:

def reverse(it):
    stack = []
    for item in it:
        stack.append(item)
    while stack:
        yield stack.pop()

当然,Python已经有一个内置堆栈,它是调用帧的堆栈。我们可以使用它来代替上面的模拟,这将引导我们进入以下递归解决方案:

def reverse(it):
    head = next(it)
    for item in reverse(it):
        yield item
    yield head

在python3中,这更加优雅:

def reverse(it):
    head = next(it)
    yield from reverse(it)
    yield head

同样,这适用于任意迭代,其长度在呼叫时是未知的。

答案 2 :(得分:2)

一种可以轻松移植到其他语言的简单算法是:

x = [1,2,3,4,5]
y = []
for i in len(x):
  y.append(x[len(x) - 1 - i])

或使用迭代器。这可以很容易移植到链接列表中使用,你不知道它的长度:

x = [1,2,3,4,5]
y = []
x_iterator = iter(x)
try:
  while (1):
    y.insert(0, x_iterator.next())
except:
  print y

或者更加pythonic版本的插入:

x = [1,2,3,4,5]
y = []
for elem in x:
  y.insert(0, elem)

答案 3 :(得分:2)

我假设你的面试官并不希望你使用内置的Python方法,而是一种更加语言无关的算法。类似的东西:

lst = [1,2,3,4,5]
lst2 = []

while len(lst) > 0:
    lst2.append(lst.pop())

lst2 = [lst.pop() for _ in lst[:]]

答案 4 :(得分:2)

这样的事情怎么样:

x = [1, 2, 3, 4, 5]

for i in xrange(len(x) / 2):
    x[i], x[-i - 1] = x[-i - 1], x[i]

print(x)

想法是从相反方向交换数组元素

答案 5 :(得分:1)

我喜欢这样:

i

基本上遍历数组的前半部分并交换len(i)-i-1<div id="adbox"> <div class="clearfix"> <img src="images/About.png" border="0" alt="Img" height="371" width="956"/> </div> </div>

答案 6 :(得分:0)

def reverse(text):
  rev = []
  for let in range(len(text),0,-1):
    rev.append(text[let-1])
  return ''.join(rev)