This question already has answers here:
python: most elegant way to intersperse a list with an element
(15 answers)
Closed 6 years ago.
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?
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)
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.
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]
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.
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]
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]
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]
Related
Input
l = [0, 0, 1, 2, 3]
I want to add 1 to index range from 2 to 3
so output should be
l = [0, 0, 2, 3, 3]
l[2:3] = l[2:3] + 1
The easiest way would be to use numpy, it's quite optimized and uses C/C++ loops under the hood, so it's blazingly fast:
>>> import numpy as np
>>> a = [0, 0, 1, 2, 3]
>>> b = np.array(a)
>>> b[2:4] += 1
>>> b
array([0, 0, 2, 3, 3])
>>>
You can try this:
for i in range(2, 4):
l[i] += 1
A possible solution can make use of list-comprehension:
l[2:4] = [x+1 for x in l[2:4]]
For a hilariously overblown solution:
from operator import add
l = [0, 0, 1, 2, 3]
deltas = [0, 0, 1, 1, 1]
result = list(map(add, l, deltas))
note that this does not modify l, but creates a new list in result
I have the following array
a = [0,0,1,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1]
I want to group every 3rd element and sum all of the elements within each group. So I can get a new array with a new size showing this sum
b = [1,0,2,0,3,0,1]
Any suggestions?
Simply, most pythonicly would be the following
b = [sum(a[i:i+3]) for i in range(0, len(a), 3)]
where your input array is a.
>>> a = [0,0,1,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1]
>>> b = [sum(a[i:i+3]) for i in range(0, len(a), 3)]
>>> b
[1, 0, 2, 0, 3, 0, 1]
You can split in chunk and sum:
step = 3
[sum(a[i:i+step]) for i in range(0, len(a),step)]
[1, 0, 2, 0, 3, 0, 1]
If the length is not the multiple of step, last chunk might be smaller.
Maybe something like this:
a = [0,0,1,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,0,1]
b = []
for i in range(0,len(a),3):
b.append(sum(a[i:i+3]))
print b
Output:
[1, 0, 2, 0, 3, 0, 1]
Another option using groupby from itertools:
from itertools import groupby
[sum(v for _, v in g) for _, g in groupby(enumerate(a), key = lambda x: x[0]/3)]
# [1, 0, 2, 0, 3, 0, 1]
Or another way to use zip:
[sum(v) for v in zip(a[::3], a[1::3], a[2::3])]
# [1, 0, 2, 0, 3, 0, 1]
I know that I can interleave two python lists with:
[elem for pair in zip(*lists) for elem in pair]
Now I need to interleave a list with a fixed element like:
list = [1, 2, 3, 4]
# 🐍 python magic 🐍
output = [1, 0, 2, 0, 3, 0, 4]
One really straightforward solution is:
[elem for x in list for elem in (x, 0)][:-1]
You can try the following itertools magic:
>>> from itertools import repeat, chain, izip
>>> l = [1, 2, 3, 4]
>>> list(chain.from_iterable(izip(l[:-1], repeat(0)))) + l[-1:]
[1, 0, 2, 0, 3, 0, 4]
from itertools import izip, repeat
start = [1, 2, 3, 4]
print [i for j in izip(start, repeat(0)) for i in j][:-1]
Python's sum function can be used on arbitrary datatypes that support addition by setting the start parameter appropriately. (see docs)
input = [1, 2, 3, 4]
fixed = 0
output = sum([[elem, fixed] for elem in input], [])[:-1] # to drop the last `fixed`
Or if you don't like the idea of using the addition operator with lists:
input = [1, 2, 3, 4]
fixed = 0
output = []
for elem in input:
output.extend([elem, fixed])
output = output[:-1]
>>> lst = [1, 2, 3, 4]
>>> newlst = [0]*((len(lst) * 2) - 1)
>>> newlst[::2] = lst
>>> newlst
[1, 0, 2, 0, 3, 0, 4]
It may not be a one-liner, but it works. Furthermore, my time tests seem to show that it's the fastest solution so far. In function form, this is:
def interzero(lst):
newlst = [0]*((len(lst) * 2) - 1)
newlst[::2] = lst
return newlst
You could use the reduce function of functools.
>>> from functools import reduce
>>> reduce(lambda x, y: x + [y, 0], [1,2,3,4], [])[:-1]
[1, 0, 2, 0, 3, 0, 4]
>>> from itertools import chain
>>> lst = [1, 2, 3, 4]
>>> list(chain(*zip(lst, [0]*(len(lst)-1)))) + [lst[-1]]
[1, 0, 2, 0, 3, 0, 4]
I need some hints or an example, how can i localize in a list a the list b, then replace it with list c.
a=[1,3,6,2,6,7,3,4,5,6,6,7,8]
input the b list (this is the sublist the program searches for in list a).
b=[6,7]
when found return me the indexes were the sublist has been found and replace it each time with c=[0,0], so the result will be
[1,3,6,2,0,0,3,4,5,6,0,0,8]
Here's a more efficient approach than my first, using list-slicing:
>>> for i in xrange(len(a) - len(b) + 1):
... if a[i:i+len(b)] == b:
... a[i:i+len(b)] = c
...
>>> a
[1, 3, 6, 2, 0, 0, 3, 4, 5, 6, 0, 0, 8]
First attempt, for posterity....
If you don't need the intermediate indices, here's one approach, using string functions and taking a functional approach, not modifying your list in-place.
>>> a_as_str = ','.join(str(i) for i in a)
>>> print a_as_str
1,3,6,2,6,7,3,4,5,6,6,7,8
>>> b_as_str = ','.join(str(i) for i in b)
>>> b_as_str
'6,7'
>>> c_as_str = ','.join(str(i) for i in c)
>>> c_as_str
'0,0'
>>> replaced = a_as_str.replace(b_as_str, c_as_str)
>>> replaced
'1,3,6,2,0,0,3,4,5,6,0,0,8'
>>> [int(i) for i in replaced.split(',')]
[1, 3, 6, 2, 0, 0, 3, 4, 5, 6, 0, 0, 8]
This can be refactored as:
>>> def as_str(l):
... return ','.join(str(i) for i in l)
...
>>> def as_list_of_ints(s):
... return [int(i) for i in s.split(',')]
...
>>> as_list_of_ints(as_str(a).replace(as_str(b), as_str(c)))
[1, 3, 6, 2, 0, 0, 3, 4, 5, 6, 0, 0, 8]
you can do something similar to (written in python 3.2, use xrange in python 2.x):
for i in range(0, len(a)):
if a[i:i+len(b)] == b:
a[i:i+len(b)] = c
this will account for lists of all sizes.
This assumes list b == list c I don't know if that is what you want however, please state if it is not.
Output for lists:
a = [1,2,3,4,5,6,7,8,9,0]
b = [1,2]
c = [0,0]
Output:
[0, 0, 3, 4, 5, 6, 7, 8, 9, 0]
I give you an example
li=[1,3,6,2,6,7,3,4,5,6,6,7,8]
for i in range(len(li)):
if li[i:i + 2] == [3, 4]:
li[i:i + 2] = [0, 0]
I think that this code should work. If you want a more robust script I suggest you to check the occurrences of a substring in the original list an edit a copy (to avoid side-effect behaviors).
It is important also to consider what happens when the given pattern is created by the substitution.
I think this function should treat all cases as intended:
def replace(a, b, c):
ii = 0
while ii <= (len(a) - len(b) + 1):
print(ii)
if a[ii:ii+len(b)] == b:
a[ii:ii+len(b)] = c
ii += len(b)
else:
ii += 1
return a
The output using the original example:
[1, 3, 6, 2, 0, 0, 3, 4, 5, 6, 0, 0, 8]
Here is an example where the substitution creates the search pattern:
a = [1,1,1,1,1,1,1,1,1,6,6,7,7,1]
b = [6,7]
c = [0,6]
Output is as expected:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 0, 6, 7, 1]
Any ideas on how to do this a bit more concisely?
I have a list of integers and I was wondering if it would be possible to add to individual integers in this list.
You can append to the end of a list:
foo = [1, 2, 3, 4, 5]
foo.append(4)
foo.append([8,7])
print(foo) # [1, 2, 3, 4, 5, 4, [8, 7]]
You can edit items in the list like this:
foo = [1, 2, 3, 4, 5]
foo[3] = foo[3] + 4
print(foo) # [1, 2, 3, 8, 5]
Insert integers into the middle of a list:
x = [2, 5, 10]
x.insert(2, 77)
print(x) # [2, 5, 77, 10]
Here is an example where the things to add come from a dictionary
>>> L = [0, 0, 0, 0]
>>> things_to_add = ({'idx':1, 'amount': 1}, {'idx': 2, 'amount': 1})
>>> for item in things_to_add:
... L[item['idx']] += item['amount']
...
>>> L
[0, 1, 1, 0]
Here is an example adding elements from another list
>>> L = [0, 0, 0, 0]
>>> things_to_add = [0, 1, 1, 0]
>>> for idx, amount in enumerate(things_to_add):
... L[idx] += amount
...
>>> L
[0, 1, 1, 0]
You could also achieve the above with a list comprehension and zip
L[:] = [sum(i) for i in zip(L, things_to_add)]
Here is an example adding from a list of tuples
>>> things_to_add = [(1, 1), (2, 1)]
>>> for idx, amount in things_to_add:
... L[idx] += amount
...
>>> L
[0, 1, 1, 0]
fooList = [1,3,348,2]
fooList.append(3)
fooList.append(2734)
print(fooList) # [1,3,348,2,3,2734]
If you try appending the number like, say
listName.append(4) , this will append 4 at last.
But if you are trying to take <int> and then append it as, num = 4 followed by listName.append(num), this will give you an error as 'num' is of <int> type and listName is of type <list>. So do type cast int(num) before appending it.
Yes, it is possible since lists are mutable.
Look at the built-in enumerate() function to get an idea how to iterate over the list and find each entry's index (which you can then use to assign to the specific list item).