1

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.

7
  • 5
    Can you please write the expected output? Commented Aug 18, 2018 at 8:34
  • The expected output should read a = [1, 1, 0, 1, 0] and b = [0, 0, 0, 0, 0] if I am not mistaken Commented Aug 18, 2018 at 9:07
  • @Grimlock How do you imagine the procedure to achieve your goal should lookalike? Commented Aug 18, 2018 at 10:08
  • @Thomas I have updated the explanation Commented Aug 18, 2018 at 11:03
  • @hygull I have written out the output now Commented Aug 18, 2018 at 11:03

4 Answers 4

1

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]
Sign up to request clarification or add additional context in comments.

5 Comments

The only problem with that is that the for loop goes through the items one by one. I need a way to go through them all simultaneously
@Grimlock Why has it to happen simultaneous?
@inder can you write that without list comprehension
@Grimlock I am sorry I don't think I follow, without list comprehension meaning ???
@Grimlock I don't think that what you request for is actually feasible… like list-comprehensions in python is "the thing" to do… somehow you need to traverse the list as there is no such thing as a "one-shot-solution" to this.
1

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

This is pretty comprehensive but you might've just succeeded in overwhelming some kid trying to get his homework done. Not that there's a problem with that, but eh...
alright so my lists are never going to be too long so I'll go with the first solution. However, if there is a 1 in list a and 0 in list b I have to go back and turn the item in list b that corresponds to 0 in list a.
0

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

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.