0

List inputed: ["a", "b", "c", "d", "e", "f", "g", "h"]

List expected: ["a", 99, "b", 99, "c", 99, "d", 99, "e", 99, "f", 99, "g", 99, "h"]

List actual: ["a", 99, "b", 99, "c", 99, "d", 99, "e", "f", "g", "h"]

Python code:

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)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343

3 Answers3

4

The for loop derefences m_l once; rebinding m_l won't change the loop.

I'd use some itertools module magic here:

from itertools import repeat, chain

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

Demo:

>>> 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']

or using insertions to alter m in-place:

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

Demo:

>>> 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']

By looping over the indices in reverse you don't have to account for the extra elements being inserted into the list.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Very elaborate, Martijin Pieters! Thanks. It worked like a charm. Looping in reverse is truly ingenious. I could never have though that. – Ami Ahmad Touseef Feb 26 '14 at 01:49
0
m = ["a", "b", "c", "d", "e", "f", "g", "h"]
output = []
for i in m:
    output.append(i)
    output.append(99)
del output[-1]
La-comadreja
  • 5,627
  • 11
  • 36
  • 64
0

I'm going to second that this is a bizarre way to accomplish what you're doing here. First, the loop is certainly not "skipping the last iteration." Your loop is ending before the last condition is hit, because your counting is wonky. In fact, if you paid closer attention to your "List actual," you would note that the loop ends shortly after 50% through the list. The reason why is quite simple: you only have N iterations (the length of m), and you aren't doing anything with half of them. When the condition is false, nothing happens, and you skip doing anything. But it's not like you get those iterations back, you've already burnt them.

A vastly simpler approach is possible in one-line, though I prefer to keep the slice on a second line to make it more obvious:

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

This iterates over the values, then iterates over a small tuple with the value and your constant, then slices the list to cut off the last element (which is an extra constant at the end). List comprehensions are pretty easy to read, provided you don't go too deep. With just two levels of iteration, this is simple and clean, plus doesn't require any spare imports.

Namey
  • 1,172
  • 10
  • 28
  • I thought the length of m_o is changing every time "99" is inserted in. This worked, thanks! – Ami Ahmad Touseef Feb 26 '14 at 01:48
  • The list length is changing, but the length that you are iterating over is calculated only once. You could in theory use a while loop to iterate over a dynamically-sized list, but that would be a horrible way to do this. I would just learn how to master list comprehensions, they're great. – Namey Feb 27 '14 at 18:25