首页 > 解决方案 > 对于奇数长度列表而不是偶数长度列表,卡在 while 循环中的 perfect_shuffle_counter

问题描述

perfect_shuffle() 接受一个列表并完美地打乱它。count_shuffle() 通过实例化 perfect_shuffle() 计算列表返回其原始状态的次数。Count_shuffle() 对于偶数长度的列表非常有效,但对于奇数长度的列表会卡在 while 循环中。请注意,我的 perfect_shuffle 函数通过在末尾附加一个占位符来处理奇数长度的列表。然后在洗牌后将其移除 - 但不要认为这是问题所在。

def count_shuffle(start):
    """
    Takes list as argument and returns count of the number of perfect 
    shuffles 
    to return to original state

    e.g.
    count_shuffle([1,2,3,4,5,6,7,8,9,10])
    Start:  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    1 :  [1, 6, 2, 7, 3, 8, 4, 9, 5, 10]
    2 :  [1, 8, 6, 4, 2, 9, 7, 5, 3, 10]
    3 :  [1, 9, 8, 7, 6, 5, 4, 3, 2, 10]
    4 :  [1, 5, 9, 4, 8, 3, 7, 2, 6, 10]
    5 :  [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
    6 :  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    Out[172]: 6

    """
    print('Start: ',start)
    current = perfect_shuffle(start)
    count = 1

    while current != start:
        print(count,': ',current)
        current = perfect_shuffle(current)
        count+=1
    print(count,': ',current)
    return count


def perfect_shuffle(a_list):
    """
    Takes a sequence as argument and returns the 'perfect shuffle' of 
    that list

    Eg. 
    In[1]: perfect_shuffle([1,2,3,4,5])
    Out[1]: [1,4,2,5,3]

    """
    perfect_list = []

    #if list length is odd, append placeholder '0' to make even (to remove later)    
    if len(a_list)%2==1:
        odd = 1
        a_list.append(0)
    else:
        odd = 0  

    # half of list length      
    half = len(a_list)//2

    a = zip(a_list[:half],a_list[half:])

    # Flattens a from list of sublists to single list
    for i in a:
        for k in i:
            perfect_list.append(k)

    # If input list length len(a_list) is odd then this removes the placeholder  at the end
    if odd:
        perfect_list = perfect_list[:-1]

    return perfect_list

标签: python-3.x

解决方案


解决方案是在a_list里面复制perfect_shuffle,并且只更改副本。例如,将 for 循环之前的部分更改为:

perfect_list = []
b_list = a_list[:]
print(id(a_list))
#if list length is odd, append placeholder '0' to make even (to remove later)    
if len(a_list)%2==1:
    odd = 1
    b_list.append(0)
else:
    odd = 0  

# half of list length      
half = len(b_list)//2

a = zip(b_list[:half],b_list[half:])

现在,您正在通过将 0 附加到它来更改开始列表,但是当前将删除 0,因此它们将永远不会相同。打印电流时输出并在您的内部开始count_shuffle

Start:  [1, 2, 3]
1 :  [1, 3, 2] [1, 2, 3, 0]
2 :  [1, 2, 3] [1, 2, 3, 0]
3 :  [1, 3, 2] [1, 2, 3, 0]

无止境。

通过调用perfect_shuffle(start),您只提供了一个指向 的指针start,然后该指针将被更改。您不是在复制列表。


推荐阅读