Python for循环不执行最后一次迭代

时间:2014-02-17 20:15:58

标签: python list

列出的名单:["a", "b", "c", "d", "e", "f", "g", "h"]

预期列表:["a", 99, "b", 99, "c", 99, "d", 99, "e", 99, "f", 99, "g", 99, "h"]

列出实际:["a", 99, "b", 99, "c", 99, "d", 99, "e", "f", "g", "h"]

Python代码:

m_o = ["a", "b", "c", "d", "e", "f", "g", "h"]
m = ["a", "b", "c", "d", "e", "f", "g", "h"]
m_expected = ["a", 99, "b", 99, "c", 99, "d", 99, "e", 99, "f", 99, "g", 99, "h"]
num = 99
count = 0
m_l = range(len(m))
for i in m_l:
    if i==(1+count):
        m.insert(i, num)
        count = count + 2
        m_l = range(len(m))
    #print("1+count : " + str(1+count))
    #print(m)
    #print("m_l: " + str(m_l))
print("List inputed: ")
print(m_o)
print("\nList expected: ")
print(m_expected)
print("\nList actual: ")
print(m)

3 个答案:

答案 0 :(得分:4)

for循环解除m_l 一次;重新绑定m_l不会改变循环。

我在这里使用了一些itertools module魔法:

from itertools import repeat, chain

m = list(chain.from_iterable(zip(m, repeat(99))))[:-1]

演示:

>>> from itertools import repeat, chain
>>> m = ["a", "b", "c", "d", "e", "f", "g", "h"]
>>> list(chain.from_iterable(zip(m, repeat(99))))[:-1]
['a', 99, 'b', 99, 'c', 99, 'd', 99, 'e', 99, 'f', 99, 'g', 99, 'h']

或使用插入来就地改变m

for i in range(len(m) - 1, 0, -1):
    m.insert(i, 99)

演示:

>>> m = ["a", "b", "c", "d", "e", "f", "g", "h"]
>>> for i in range(len(m) - 1, 0, -1):
...     m.insert(i, 99)
... 
>>> m
['a', 99, 'b', 99, 'c', 99, 'd', 99, 'e', 99, 'f', 99, 'g', 99, 'h']

通过循环遍历索引反向,您不必考虑插入列表中的额外元素。

答案 1 :(得分:0)

m = ["a", "b", "c", "d", "e", "f", "g", "h"]
output = []
for i in m:
    output.append(i)
    output.append(99)
del output[-1]

答案 2 :(得分:0)

我要说的是,这是完成你在这里所做的一种奇怪的方式。首先,循环当然不是“跳过最后一次迭代”。你的循环在最后一个条件被击中之前结束,因为你的计数是不稳定的。事实上,如果你更加关注你的“列出实际”,你会注意到循环在列表的50%之后很快就会结束。原因很简单:你只有N次迭代(m的长度),并且你没有做其中一半的任何事情。当条件为假时,没有任何反应,你跳过任何事情。但是,这并不像你得到那些迭代,你已经把它们烧掉了。

在单行中可以采用一种更简单的方法,但我更喜欢将切片保留在第二行以使其更明显:

m = [x for val in m_o for x in (val, 99)]
m[:] = m[:-1]

迭代这些值,然后使用值和常量迭代一个小元组,然后对列表进行切片以切断最后一个元素(最后是一个额外的常量)。列表理解很容易阅读,只要你不太深入。只需两个级别的迭代,这很简单干净,而且不需要任何备用导入。