以递归方式按特定顺序随机播放列表

时间:2014-02-17 23:08:13

标签: python recursion

我正在尝试按特定顺序递归地重排列表。

我有:

def shuffle(list1, list2):
    a = []
    if len(list1) == 0:
        a += list2
        return a
    if len(list2) == 0:
        a += list1
        return a
    else:
        a += [list1[0]]
        list1.pop(0)
        a += [list2[0]]
        list2.pop(0)
    return a += shuffle(list1, list2)

4 个答案:

答案 0 :(得分:3)

您的核心问题是您没有返回递归通话。清理代码中一些名义上未使用的本地人会给出:

def shuffle(list1, list2):
    a = []
    if len(list1) == 0:
        return list2
    if len(list2) == 0:
        return list1
    else:
        a.append(list1.pop(0))
        a.append(list2.pop(0))
    return a + shuffle(list1, list2)

当然在上面的清理中你很明显甚至不需要a累加器:

def shuffle(list1, list2):
    if len(list1) == 0:
        return list2
    if len(list2) == 0:
        return list1
    else:
        return [list1.pop(0),list2.pop(0)] + shuffle(list1, list2)

演示:

shuffle([1,2,3],[4,5,6])
Out[35]: [1, 4, 2, 5, 3, 6]

shuffle([1,2], [6,7,8,9])
Out[36]: [1, 6, 2, 7, 8, 9]

顺便说一句,这会改变输入列表,这通常是不可取的。使用切片而不是pop ping元素可以更好地服务:

def shuffle(list1, list2):
    if len(list1) == 0:
        return list2
    if len(list2) == 0:
        return list1
    else:
        return [list1[0],list2[0]] + shuffle(list1[1:], list2[1:])

答案 1 :(得分:0)

from itertools import chain

def shuffle(list1, list2):
    if len(list1)==len(list2): return list(chain(*zip(list1,list2)))
    # if the lists are of equal length, chaining the zip will be faster
    else:
        a = []
        while any([list1,list2]):
            for lst in (list1,list2):
                try: a.append(lst.pop(0))
                except IndexError: pass
        return a
    # otherwise, so long as there's items in both list1 and list2, pop the
    # first index of each (ignoring IndexError since one might be empty)
    # in turn and append that to a, returning the value when both lists are
    # empty.

这不是您正在寻找的递归解决方案,但是明确的解决方案通常更快,更容易阅读和调试。 @DSM指出这可能是一个功课问题,所以我为误读道歉。我会继续这样做,以防它对任何人有启发。

答案 2 :(得分:0)

  

如何使用递归模型使这个函数适用于这些情况?

对于递归中的每个步骤,其中两个列表都是非空的,您将创建一个新的临时数组“a”,但之后不会对它执行任何操作。

你需要通过引用向下传递你存储结果的列表递归链(首选 - 它是零拷贝),或者返回列表片段并在解除递归时将其附加到结果数组(功能,但是需要每次创建一个新的列表对象,这很慢。)

答案 3 :(得分:0)

生成器版本,只是因为生成器很棒^^

def shuffle(a,b):
    A = iter(a)
    B = iter(b)

    while True: 
        try:
            yield A.next()
        except StopIteration:
            for j in B: 
                yield j 
            break
        try:
            yield B.next()
        except StopIteration:
            for j in A:
                yield j
            break

print list(shuffle(a,b))