combination using nested for loops
本问题已经有最佳答案,请猛点这里访问。
我问题的简化版本是:我写了这个代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | string = ['A','A','A','A'] temp=string[:] f=open('combin.txt', 'a') for x1 in range(0,2): if x1==1: temp[0]='X' for x2 in range(0,2): if x2==1: temp[1]='X' for x3 in range(0,2): if x3==1: temp[2]='X' for x4 in range(0,2): if x4==0: f.write(''.join(temp)+' ') if x4==1: temp[3]='X' f.write(''.join(temp)+' ') |
结果是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | AAAA AAAX AAXX AAXX AXXX AXXX AXXX AXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX |
号
但我期望的是这些组合:美国航空航天协会AAAX阿克萨AXAAXAAAXX斧萨克斯XXAA厦华阿克萨AXXXXAXXXXAXXXXAXXXX
注意,在最终的程序中,我需要在每个if条件下做很多操作,所以它不是一个简单的字符串迭代,但首先我想让这个组合部分工作。非常感谢你的帮助。
您可以使用内置库itertools,它具有"组合"功能,或者您可以认识到您实际上是在表示二进制数:
1 2 | for s in [bin(n)[2:].zfill(4) for n in xrange(2 ** 4)]: print s.replace('0','A').replace('1','X') |
上述代码:
您所做的操作可以基于范围的数量,在这种情况下,您可以将字符串格式移动到循环体中(当然,如果您知道将要执行哪种操作,这将有所帮助)
1 2 3 4 5 6 7 | for n in xrange(2 ** 4): if n & 0b1000: # If the first character is 'X' # operations here if n & 0b0100: # If the second character is 'X' # other operations # ... more checks/operations ... print bin(n)[2:].zfill(4).replace('0','A').replace('1','X') |
号
以下是一种不太直观的显示组合的方法:
1 2 3 4 5 6 7 8 | def gen(s): if len(s) == 4: print s return gen(s+'A') gen(s+'X') # which you would run with: gen('') |
代码的问题在于,您将
1 2 | for x1 in 'AX': temp[0] = x1 |
。
你甚至可以把它变成一个大的清单理解:
1 2 3 | >>> [x1+x2+x3+x4 for x1 in 'AX' for x2 in 'AX' for x3 in 'AX' for x4 in 'AX'] ['AAAA', 'AAAX', 'AAXA', 'AAXX', 'AXAA', 'AXAX', 'AXXA', 'AXXX', 'XAAA', 'XAAX', 'XAXA', 'XAXX', 'XXAA', 'XXAX', 'XXXA', 'XXXX'] |
。
当然,正确的方法是使用
1 2 3 | >>> [''.join(comb) for comb in itertools.product('AX', repeat=4)] ['AAAA', 'AAAX', 'AAXA', 'AAXX', 'AXAA', 'AXAX', 'AXXA', 'AXXX', 'XAAA', 'XAAX', 'XAXA', 'XAXX', 'XXAA', 'XXAX', 'XXXA', 'XXXX'] |
因此,您可以在一行可读的代码中创建"组合",然后迭代该列表,在一个更干净的循环中做您需要做的任何事情。
如果您在实际程序中确实需要所有的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | for x1 in range(0,2): if x1==0: temp[0]='A' if x1==1: temp[0]='X' for x2 in range(0,2): if x2==0: temp[1]='A' if x2==1: temp[1]='X' for x3 in range(0,2): if x3==0: temp[2]='A' if x3==1: temp[2]='X' for x4 in range(0,2): if x4==0: temp[3]='A' if x4==1: temp[3]='X' print(''.join(temp)) |
。
它提供以下输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | AAAA AAAX AAXA AAXX AXAA AXAX AXXA AXXX XAAA XAAX XAXA XAXX XXAA XXAX XXXA XXXX |
注意最后一个字母变化最快,因为它是由最内部的