consider:
a = [1, 1, 0, 1, 2]
b = [3, 2, 2, 0, 0]
I have to make take all items in list b that correspond to the value of 1 in the list a. Then change all occurrences to those items in both lists to 0.
Important Edit: I also have to take these items as input.
I have to also do this simultaneously for all items.
I have tried using a for loop to do this but for loop goes through the list one by one instead of all together.
I am honestly confused on how to approach this. Any help is appreciated! Thanks! NOTE: Has to be python 3.X
Super Edit: (Sorry I didn't do this earlier)
I want the code to go something like this:
input:
a = [1, 1, 0, 1, 2]
b = [3, 2, 2, 0, 0]
count = 0
output:
a = [0, 0, 0, 0, 0]
b = [0, 0, 0, 0, 0]
count = 1
where count is supposed to increment as the numbers are changed. Thus I have to go through the lists and do the steps described above simultaneously for all items and lists. Sorry I didn't put this up earlier.
4 Answers 4
if you want to do what you are asking and are looking for speed this will work:
[0 if x in b else x for x in a]
This will work, I am sure but slower than the above approach. But this will help in better understanding.
newa=[]
for i in a:
if i in b:
newa.append(0)
else:
newa.append(i)
the newa will be :
[1, 1, 0, 1, 0]
5 Comments
A first solution, using a loop:
def with_loop(a, b):
out = []
for index, val in enumerate(a):
if val == 1:
out.append(b[index])
a[index] = 0
b[index] = 0
return out
a = [1, 1, 0, 1, 2]
b = [3, 2, 2, 0, 0]
print(with_loop(a, b))
# [3 2 0]
print(a)
# [0 0 0 0 2]
print(b)
# [0 0 2 0 0]
Some timings:
a = [1, 1, 0, 1, 2]
b = [3, 2, 2, 0, 0]
%timeit with_loop(a, b)
# 1000000 loops, best of 3: 806 ns per loop
a = [1, 1, 0, 1, 2]*20
b = [3, 2, 2, 0, 0]*20
%timeit with_loop(a, b)
#100000 loops, best of 3: 7.3 μs per loop
a = [1, 1, 0, 1, 2]*400
b = [3, 2, 2, 0, 0]*400
%timeit with_loop(a, b)
# 10000 loops, best of 3: 165 μs per loop
If your lists are large, it could be good to use numpy:
import numpy as np
a = np.array([1, 1, 0, 1, 2])
b = np.array([3, 2, 2, 0, 0])
def with_numpy(a, b):
out = b[a == 1]
b[a == 1] = 0
a[a == 1] = 0
return out
print(with_numpy(a, b))
# [3 2 0]
print(a)
# [0 0 0 0 2]
print(b)
# [0 0 2 0 0]
Again, some timings:
a = np.array([1, 1, 0, 1, 2])
b = np.array([3, 2, 2, 0, 0])
%timeit with_numpy(a, b)
#100000 loops, best of 3: 5.02 μs per loop
a = np.array([1, 1, 0, 1, 2]*20)
b = np.array([3, 2, 2, 0, 0]*20)
%timeit with_numpy(a, b)
#100000 loops, best of 3: 5.34 μs per loop
a = np.array([1, 1, 0, 1, 2]*400)
b = np.array([3, 2, 2, 0, 0]*400)
%timeit with_numpy(a, b)
#100000 loops, best of 3: 13.9 μs per loop
For small lists, using numpy has a big overhead, but it gets faster than the pure Python loops solution with lists less than 100 items long, and is more than 10 times faster for 2000 items.
2 Comments
You could use a generator which inspects both sequences and yields their current and future values:
def gen(a,b):
for i in len(a):
if a[i]==1:
yield b[i] # need some cleverness about how we unpack this
yield (0,0)
else:
yield None
yield (a[i],b[i])
Then something like assign a,b = list(gen(a,b)). We'll need extra code to unpack the current nonzero elements of b
Comments
Considering that you want to remove the 1s from list a too, please have a look at this solution proposal:
>>> x, y = map(list, zip(*[(0 if i==1 else i, 0 if i==1 else j) for i, j in zip(a, b)]))
>>> print('x: {}, y: {}'.format(x, y))
x: [0, 0, 0, 0, 2], y: [0, 0, 2, 0, 0]
Please keep in mind that there actually is a need to traverse the list and that there is no other way to do this except going through the list one by one.
a = [1, 1, 0, 1, 0]andb = [0, 0, 0, 0, 0]if I am not mistaken