以一定的顺序递归地洗牌列表

2024-04-25 07:46:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图按一定的顺序递归地洗牌。在

我有:

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)

Tags: lenreturnif顺序defpopelseshuffle
3条回答

How can I make this function work these cases using a recursive model?

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

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

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指出这很可能是一个家庭作业问题,所以我为误读道歉。我先把这个留着,以防对任何人有启发。在

你的中心问题是你没有返回递归调用。清理代码中一些名义上未使用的局部变量可以得到:

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累加器:

^{pr2}$

演示:

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]

另外,这会改变输入列表,这通常是不可取的。使用切片而不是popping元素可能会更好地为您服务:

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:])

相关问题 更多 >