2014-02-17 74 views
0

列表:["a", "b", "c", "d", "e", "f", "g", "h"]的Python循环将不会执行inputed最后一次迭代

名单预计:["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) 
+0

'append'好像比这个代码中的insert更好。 –

+2

毛。不要写你自己的功能来做到这一点。 http://stackoverflow.com/q/2407398/139010 –

+0

我刚刚第一次学习Python。在掌握Python基础知识之后,我将使用现有的方法。 –

回答

4

for环derefences 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'] 

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

+0

非常详尽,Martijin彼得斯!谢谢。它像一个魅力。反向循环确实是巧妙的。尽管如此,我永远不会有。 –

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

这是像我这样的初学Python程序员的最简单的方法。谢谢! –

0

我要第二次说,这是一种奇怪的方式来完成你在这里做的事情。首先,循环肯定不是“跳过最后一次迭代”。你的循环在最后一个条件被打中之前就结束了,因为你的计数很不稳定。事实上,如果您更加关注“实际列表”,您会注意到该循环在列表中的50%后不久就会结束。原因很简单:你只有N次迭代(m的长度),并且你没有对其中的一半做任何事情。当条件不成立时,什么都不会发生,你会跳过任何事情。但它不像你把这些迭代回来,你已经烧毁了它们。

一个大大简单的方法是有可能在一个行,但我宁愿保持切片在第二行以使其更明显:

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

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

+0

我以为每次插入“99”时,m_o的长度都会发生变化。这很有效,谢谢! –

+0

列表长度正在改变,但您正在迭代的长度仅计算一次。理论上你可以使用一个while循环遍历一个动态大小的列表,但这是一个可怕的方式来做到这一点。我只会学习如何掌握列表解析,他们很棒。 – Namey