Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:嵌套循环的程序不工作_Python_Permutation - Fatal编程技术网

Python:嵌套循环的程序不工作

Python:嵌套循环的程序不工作,python,permutation,Python,Permutation,该程序需要通过使用以下规则交换元素来查找列表的所有排列-交换最后一个元素,直到它成为第一个(例如,1、2、3、4变成1、2、4、3等等,直到4、1、2、3),当它成为第一个元素时,您需要切换最后两个元素,并以相反的方向执行相同的操作(交换第一个元素直到它变为最后一个,然后交换前2个元素并重复),这也被称为Steinhaus-Johnson-Trotter算法。出于某种原因,我的实现无法在Python中工作,我想知道为什么以及需要做什么才能使它工作 编辑:我所说的“不工作”是指程序只打印列表1,不

该程序需要通过使用以下规则交换元素来查找列表的所有排列-交换最后一个元素,直到它成为第一个(例如,1、2、3、4变成1、2、4、3等等,直到4、1、2、3),当它成为第一个元素时,您需要切换最后两个元素,并以相反的方向执行相同的操作(交换第一个元素直到它变为最后一个,然后交换前2个元素并重复),这也被称为Steinhaus-Johnson-Trotter算法。出于某种原因,我的实现无法在Python中工作,我想知道为什么以及需要做什么才能使它工作

编辑:我所说的“不工作”是指程序只打印列表1,不做任何其他事情,程序只能通过“杀死”它来关闭,这意味着它被卡在无限循环中(这可以通过在所有列表1附加到所有列表排列后打印所有列表排列来证明)


此处的这段代码将导致无限循环。如果
所有排列
的长度不是23,它将命中
continue
语句。这将在不修改
x
所有排列
的情况下将程序发送回循环的开头

我相信你在这里寻找的是
pass
,它什么也不做。
continue
将返回到循环的开始。因此,要修复程序的这一部分,你实际上可以完全去掉
else
,因为
中断
将退出循环,因此不需要它

while x != 3:  
    if len(all_permutations) == 23:  
        break
    x += 1
    list1[x-1], list1[x] = list1[x], list1[x-1]  
    all_permutations.append(list1)
或者,您可以删除
,如果

while x != 3 or len(all_permutations) != 23:  
    x += 1
    list1[x-1], list1[x] = list1[x], list1[x-1]  
    all_permutations.append(list1)

您正在将对同一列表对象的多个引用添加到
所有排列
,并且该列表对象在循环中每次都会被修改。相反,请添加列表的副本,以便拥有不同排列的集合

list1 = [0, 1, 2, 3] #list that will be swapped
x = 3  #this is used for swapping

all_permutations = [] #list where permutations will be added

print(list1) #print list1 because it is the first permutation

while len(all_permutations) != 23:  #loop until all permutations are found (4! = 24 but since list1 is already 1 permutation we only need 23)
    x -= 1
    list1[x], list1[x+1] = list1[x+1], list1[x]
    all_permutations.append(list1)   

                               #code above swaps the last element until it becomes 1st in the list
    if x == 0:  #if last element becomes 1st
        list1[2], list1[3] = list1[3], list1[2]  #swap last 2 elements
        while x != 3:  #loop which swaps 1st element until it becomes the last element
            if len(all_permutations) == 23:  
                break
            else:
                continue
            x += 1
            list1[x-1], list1[x] = list1[x], list1[x-1]  
            all_permutations.append(list1)


        list1[0], list1[1] = list1[1], list1[0] #when loop is over (when 1st element becomes last) switch first 2 elements
        all_permutations.append(list1)


    else:
        continue



print(all_permutations) #print all permutations
all_permutations.append(list1[:])

这是一个错误;无限循环是由IanAuld指出的问题造成的。

新代码陷入无限循环的原因是当
len(所有置换)==23
在内部
中变为真,而
循环则在第30行追加另一个列表。当控件到达外部循环
len(所有置换)==24
的顶部时,循环继续执行

这很容易修复,但是您的算法并不十分正确。我修改了您的代码以生成任意大小列表的排列,并注意到它对长度为3或4的列表给出了正确的结果,但对长度为2或5的列表则没有;我没有测试其他大小的列表

FWIW,这是一个实现Steinhaus-Johnson-Trotter算法递归版本的程序。如果您想改进迭代算法,您可能会发现它很有用

#!/usr/bin/env python

''' Generate permutations using the Steinhaus - Johnson - Trotter algorithm

    This generates permutations in the order known to bell ringers as
    "plain changes".
    See https://en.wikipedia.org/wiki/Steinhaus%E2%80%93Johnson%E2%80%93Trotter_algorithm

    From http://stackoverflow.com/q/31209826/4014959

    Written by PM 2Ring 2015.07.03
'''

import sys

def sjt_permute(items):
    num = len(items)
    if num == 1:
        yield items[:1]
        return

    last = items[-1:]
    uprange = range(num)
    dnrange = uprange[::-1]
    descend = True
    for perm in sjt_permute(items[:-1]):
        rng = dnrange if descend else uprange
        for i in rng:
            yield perm[:i] + last + perm[i:]
        descend = not descend

def main():
    num = int(sys.argv[1]) if len(sys.argv) > 1 else 4
    items = range(num)
    for p in sjt_permute(items):
        print(p)

if __name__ == '__main__':
    main()
输出

[0, 1, 2, 3]
[0, 1, 3, 2]
[0, 3, 1, 2]
[3, 0, 1, 2]
[3, 0, 2, 1]
[0, 3, 2, 1]
[0, 2, 3, 1]
[0, 2, 1, 3]
[2, 0, 1, 3]
[2, 0, 3, 1]
[2, 3, 0, 1]
[3, 2, 0, 1]
[3, 2, 1, 0]
[2, 3, 1, 0]
[2, 1, 3, 0]
[2, 1, 0, 3]
[1, 2, 0, 3]
[1, 2, 3, 0]
[1, 3, 2, 0]
[3, 1, 2, 0]
[3, 1, 0, 2]
[1, 3, 0, 2]
[1, 0, 3, 2]
[1, 0, 2, 3]

你能比“不工作”更具体一点吗?它只打印列表1(它在外循环),很明显程序卡在无限循环中(这可以通过在所有列表1附加到所有列表置换后立即打印所有列表置换来证明)。请编辑问题以提供所有必要的信息。
所有排列
包含对同一列表对象的多个引用,您每次通过while循环都会不断修改这些引用。@chepner那么我需要更改什么?谢谢,但我仍然有一个问题,我忘记添加一行代码,因此会有重复排列,这是我忘记添加的内容(经过您和chepner的修改),奇怪的是这行代码将使程序永远执行,没有它,程序将运行良好(但当然会再次找到相同的排列),为什么这行代码会破坏程序?实际上破坏了OP的有效语法。。。
[0, 1, 2, 3]
[0, 1, 3, 2]
[0, 3, 1, 2]
[3, 0, 1, 2]
[3, 0, 2, 1]
[0, 3, 2, 1]
[0, 2, 3, 1]
[0, 2, 1, 3]
[2, 0, 1, 3]
[2, 0, 3, 1]
[2, 3, 0, 1]
[3, 2, 0, 1]
[3, 2, 1, 0]
[2, 3, 1, 0]
[2, 1, 3, 0]
[2, 1, 0, 3]
[1, 2, 0, 3]
[1, 2, 3, 0]
[1, 3, 2, 0]
[3, 1, 2, 0]
[3, 1, 0, 2]
[1, 3, 0, 2]
[1, 0, 3, 2]
[1, 0, 2, 3]