繁体   English   中英

递归地打乱列表

[英]Shuffle a list recursively

我试图递归地洗牌一个列表,它的数字在1 - 13之间,这样偶数索引中的每个数字都将位于列表的右侧,而奇数索引中的数字将位于新的左侧列表。
例如采取l=[1, 13, 10, 1, 5, 2, 5, 3]
Function 应该返回: [1, 10, 5, 5, 13, 1, 2, 3]
这是我的工作:

def shuffle(arr, start, stop):
   if stop == 0:
       return [arr[stop-1]]
   return [arr[start]] + shuffle(arr, start + 2, stop - 2) + [arr[stop-1]]

注意: start =0, stop = len(arr) (当然,数组的长度是 2 的幂)。

我的代码 output 是[1, 10, 5, 5, 3, 13, 1, 2, 3] ,我已经尝试了几个小时来摆脱中间的额外3 ,但我真的很难过.
当我写返回时,我考虑解决一个较小的问题,这就是我通常处理递归答案的方式,我将第一个偶数放入列表的左侧,然后发送“较小”的列表,然后放回列表中的最后一个奇数。

我真的很感激如何解决这个问题的任何帮助,我试图克服这个问题几个小时,我觉得理解如何解决这个问题将帮助我更多地理解递归。
提前致谢。

编辑:对不起,如果不清楚,但我知道如何正常解决它,我的目标是递归地解决它。

不要使用startstop ,而是尝试使用单个index并使用负索引从右侧遍历列表:

l=[1, 13, 10, 1, 5, 2, 5, 3]

def shuffle(arr, index=0):
  if index >= len(arr):
    return []
  return [arr[index]] + shuffle(arr, index + 2) + [arr[-1-index]]

print(shuffle(l))

这种方法仅适用于具有偶数个元素的列表,但根据您告诉我们的内容应该没问题。

您可以对列表进行分区,并且只对左右部分的改组进行递归:

from random import choice

def shuffle(A,left=None,done=0):
  if left is None:
    A    = A[::2]+A[1::2]   # partition list
    left = len(A[1::2])     # compute left size for recursion
  if done>left:return A     # all shuffled
  if done<left:            
      rLeft  = choice(range(done,left))            # shuffle left part
      A[done],A[rLeft] = A[rLeft],A[done]
  if left+done<len(A):
      rRight = choice(range(left+done,len(A)))     # shuffle right part
      A[-1-done],A[rRight] = A[rRight],A[-1-done]
  return shuffle(A,left,done+1)                    # recurse

output:

L = [1, 13, 10, 1, 5, 2, 5, 3]

print(shuffle(L))
[10, 5, 5, 1, 2, 1, 3, 13]

直接创建一个新列表对我来说感觉更干净:

def shuffle(array):
    return array[0::2] + array[1::2]

l = [1, 13, 10, 1, 5, 2, 5, 3]
print(shuffle(l))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM