2

I have a list like

[1, 2, 3, 4, 5]

and I want to add zeroes at odd indexes:

[1, 0, 2, 0, 3, 0, 4, 0, 5]

My first thought was to create a list with zeroes and replace them with the values from the original list.

listOfZeros = [0] * (2*len(list)-1)
    j = 0
    for i in range(0, len(listOfZeros)):
        if (i%2 == 0):
            listOfZeros[i] = h_temp[j]
            j += 1

This actually works, but I do dislike for loops and adding another counter j. Isn't there a better way by using slicing?

Vincent Savard
  • 34,979
  • 10
  • 68
  • 73

7 Answers7

3

one way is by using zip:

a = [1, 2, 3, 4, 5]
d = [x for t in zip (a, [0] * len(a)) for x in t][:-1]

When you use zip, you create list of tuples.

a = [1,2,3,4,5]
b = [0,0,0,0,0]
c = zip(a,b)
#zip (a,b) creates [(1,0),(2,0),(3,0),(4,0),(5,0)]

Then you loop over the set of tuples to arrange them into list:

d = [x for t in c for x in t] #creates [1,0,2,0,3,0,4,0,5,0]

and cut the last element (since you end with 5)

[x for t in c for x in t][:-1] #take out the last 0
#resulting in [1,0,2,0,3,0,4,0,5]

then you are done.

Ian
  • 30,182
  • 19
  • 69
  • 107
3

You can use insert(). Looking at your output, assuming you are not counting index 0 as even.

a = [1,2,3,4,5]
for x in range(len(a)):
    a.insert(2*x+1, 0)
Lafexlos
  • 7,618
  • 5
  • 38
  • 53
  • I don't think that inserting into a list of changing length should be recommended. There are better solutions with a generator or with `itertools` (in my opinion at least). – Jared Goguen Mar 12 '16 at 09:14
2

You can do it with a generator:

def zero_on_odd(mylist):
    for i in mylist:
        yield i
        yield 0

a = [1, 2, 3]
with_zeros = list(zero_on_odd(a))[:-1]
loutre
  • 874
  • 8
  • 16
2

If you want to go functional...

from itertools import chain, repeat

_list = [1,2,3,4,5]
list(chain(*zip(_list, repeat(0))))[:-1]
# [1, 0, 2, 0, 3, 0, 4, 0, 5]

If you want to be silly...

[int(i) for i in '0'.join(str(i) for i in _list)]
# still [1, 0, 2, 0, 3, 0, 4, 0, 5]

Or, if you want to be functional AND silly...

map(int, '0'.join(map(str, _list)))
# really, it's still [1, 0, 2, 0, 3, 0, 4, 0, 5]
# except in Python 3.X, there it's a map object...

But, you should probably opt for one of the custom generator solutions.

Jared Goguen
  • 8,772
  • 2
  • 18
  • 36
1

Another zip way:

>>> li
[1, 2, 3, 4, 5]
>>> [e for t in  zip(li,[0]*(len(li)-1)) for e in t]+[li[-1]]
[1, 0, 2, 0, 3, 0, 4, 0, 5]

You can also use range and slice assignment:

>>> li=[1,2,3,4,5]
>>> for i in range(1,len(li)+len(li)-1, 2): li[i:i]=[0]
... 
>>> li
[1, 0, 2, 0, 3, 0, 4, 0, 5]

And, a list comprehension:

>>> [li[i/2] if not i%2 else 0 for i in range(len(li)*2-1)]
[1, 0, 2, 0, 3, 0, 4, 0, 5]
dawg
  • 98,345
  • 23
  • 131
  • 206
1

For the fun of it, here is an itertools solution:

from itertools import islice, chain

data = [1,2,3,4,5]
print list(islice(chain.from_iterable((x, 0) for x in data), 0, 2 * len(data)-1))

Giving:

[1, 0, 2, 0, 3, 0, 4, 0, 5]
Martin Evans
  • 45,791
  • 17
  • 81
  • 97
0

A hacky way:

>>> ls1 = [1, 2, 3, 4, 5]
>>> ls2 = []
>>> list(ls2.extend([n, 0]) for n in ls1)
[None, None, None, None, None]
>>> ls2
[1, 0, 2, 0, 3, 0, 4, 0, 5, 0]
L3viathan
  • 26,748
  • 2
  • 58
  • 81