在python中嵌套for循环 - 可以解释一下

时间:2017-09-27 19:30:22

标签: python string list loops for-loop

我正在研究如何使用for循环等等,我正试图想出一种方法来使一串相似的字符排序,以便不重复任何字符

# string of characters
chars = 'abbbababa'
# my idea was to make it an enumerated string
charsnum = enumerate(chars)
# while doing that I discovered the following
chars = 'babbbaba'
for i in charsnum:
    for j in charsnum:
        for z in charsnum:
            for k in charsnum:
                print(i,j,z,k)
# each time I add a loop the string becomes shorter 
(0, 'b') (1, 'a') (2, 'b') (3, 'b')
(0, 'b') (1, 'a') (2, 'b') (4, 'b')
(0, 'b') (1, 'a') (2, 'b') (5, 'a')
(0, 'b') (1, 'a') (2, 'b') (6, 'b')
(0, 'b') (1, 'a') (2, 'b') (7, 'a')

我知道第一个循环迭代通过 charsnum 中的所有值,但是循环迭代的第二个,第三个等等是什么? 另外,将我的字符串'babbbaba'变成'bababababa'或'ababababa'之类的字符串可能是一个很好的解决方案。

3 个答案:

答案 0 :(得分:5)

你要求几个for循环 all 遍历同一个迭代器。您没有创建副本,它们共享一个对象。

外部循环使charsnum对象前进一步,然后下一个for循环前进一次以启动迭代,依此类推。最里面的for循环将剩余的项目进行迭代,当您返回for z循环时,没有任何内容可以迭代。

你可以做同样的事情,使用next() function推进像for那样的迭代器:

>>> chars = 'abbbababa'
>>> charsnum = enumerate(chars)
>>> i = next(charsnum)
>>> j = next(charsnum)
>>> z = next(charsnum)
>>> k = next(charsnum)
>>> i, j, z, k
((0, 'a'), (1, 'b'), (2, 'b'), (3, 'b'))
>>> next(charsnum)  # next k value in the innermost loop
(4, 'a')
>>> # etc. etc.

您可以为每个enumerate()循环创建单独的for个对象:

for i in enumerate(chars):
    for j in enumerate(chars):
        for z in enumerate(chars):
            for k in enumerate(chars):
                print(i,j,z,k)

但这比你需要的还要多。对于重复相同迭代的嵌套循环,使用itertools.product()并告诉它重复;它会根据需要保留副本:

from itertools import product

for i, j, z, k in product(enumerate(chars), repeat=4):
    print(i, j, z, k)

然而,这不会消除重复的字符;从(index, char)字符串中生成所有可能的元组中的4 char个元组的笛卡尔积。

您可能希望通过独特的字母创建排列,并将这些排列的模式排列成相同的长度:

from itertools import permutations

for pattern in permutations(set(chars)):
    repeat = (len(chars) + 1) // len(pattern)
    result = (''.join(pattern) * repeat)[:len(chars)]
    print(result)

这会产生

babababab
ababababa

答案 1 :(得分:0)

“问题”不在for循环,而在charsnum。对象charsnum是一个生成器,每次调用时都会生成下一个值。

在第一个for循环(for j in charsnum)中,它对chars中的第一个项目进行了评价,但在内循环(for z in charsnumcharsnum中会大喊大叫chars中的下一项。所以这个内部循环永远不会访问chars中的第一个项目。

答案 2 :(得分:0)

您的问题和示例确实令人困惑,我认为这就是您要找的。

更简单的方法是使用列表推导,它将以更紧凑的pythonic方式迭代您的字符集。

chars = 'abbbababa'
print( [i for i in chars] )

结果:

a
b
b
b
a
b
a
b

现在,您可以迭代索引以检查它们是否与之前的索引相同。

win = [i for i in chars]      # Convert chars string to a list of chars
last = ''                     # Create a variable to hold our last result
for i in win:
    if i != last:
        print(i)
    last = i                  # Set last to equal the last char iterated

结果:

a
b
a
b
a
b
a

或者如果你想用一个字符串打印出来......

win = [i for i in chars]      # Convert chars string to a list of chars
last = ''                     # Create a variable to hold our last result
newchars = ''
for i in win:
    if i != last:
        newchars += i
    last = i                  # Set last to equal the last char iterated
print(newchars)

结果

abababa