0

so im given two lists

lst1 =[0,1,1,1,0]
lst2 =[0,0,1,1,0]

and i need to see which index in both lists have the value 1 here is my code so far

x = list(zip(lst1,lst2))
for i in range(len(x)):
    flag = 0
    for y in range(len(x[i])):
        if x[i][y] == 1:
            flag +=1
    if flag == 2:
        z = x.index(x[i])
        print(z)

but this prints the index 2 and 2 instead of 2 and 3 can anyone point out the problem here, thanks

asyl
  • 31
  • 1
  • 5

7 Answers7

2

Assuming they're of the same length, you could use this:

>>> [i for i, (x, y) in enumerate(zip(lst1, lst2)) if x == y == 1]
[2, 3]
blacksite
  • 12,086
  • 10
  • 64
  • 109
1

You could do the following:

lst1 =[0,1,1,1,0]
lst2 =[0,0,1,1,0]
assert len(lst1) == len(lst2)

idx = [i for i in range(len(lst1)) if lst1[i] == 1 and lst2[i] == 1]

print(idx)

Other solution using numpy is:

import numpy as np

lst1 =[0,1,1,1,0]
lst2 =[0,0,1,1,0]
assert len(lst1) == len(lst2)
lst1_ = np.array(lst1)
lst2_ = np.array(lst2)

idx_ = np.intersect1d(np.where(lst1_ == 1)[0],np.where(lst2_ == 1)[0])
print(list(idx_))

Other alternative is to switch the following line:

idx_ = np.intersect1d(np.where(lst1_ == 1)[0],np.where(lst2_ == 1)[0])

By:

idx_ = np.where((lst1_==1)&(lst2_==1))[0]

As stated by @yatu is to use bitwise operations.

David
  • 8,113
  • 2
  • 17
  • 36
1

Many answers available on how to do it better.

With respect to your code snippet, List.index always gives the first matching element in the list. That's the reason we are 2,2

>>> lst1 =[0,1,1,1,0]
>>> lst2 =[0,0,1,1,0]
>>> x = list(zip(lst1,lst2))
>>> x
[(0, 0), (1, 0), (1, 1), (1, 1), (0, 0)]
>>> x.index((1,1))
2
>>> x.index((1,1))
2
  • ah so thats why even if i = 3 in the for loop it still prints the first the value that is equal to (1,1) which is index 2, thanks – asyl May 05 '20 at 15:53
0

You can iterate the over the values pairs and their index in one loop:

for idx, (i, j) in enumerate(zip(lst1, lst2)):
    if i == j == 1:
        print(idx)
Gabio
  • 9,126
  • 3
  • 12
  • 32
0

You could do this with element-wise and:

l = [i for i, _ in enumerate(lst1 and lst2) if _ == 1]

With the and function, only in cases where both lists' elements have a value of 1, will the expression return 1, which seems perfect for your question.

ccl
  • 2,378
  • 2
  • 12
  • 26
  • Indeed it is. See [here](https://stackoverflow.com/a/32192248/9698684) @marat Btw normally `_` is convention for variables that will not be used, which isn't the case here – yatu May 05 '20 at 16:12
  • @yatu the link itself is to SO, not official documentation. The link in the referred post leads to Python docs, but it doesn't say anything about special behavior on iterables. I did not have any questions about `_` - this is a well known convention. – Marat May 05 '20 at 17:08
  • Its not in the docs because it is a "side effect" of the actual behaviour of the boolean operators. But is it well known. The link is just an explanation of the "why". I don't know what you mean with `I did not have any questions about _ - this is a well known convention` – yatu May 05 '20 at 17:11
  • 1
    @yatu OK, I see now. The confusing part: @ccl answer implies that `and` will be applied element-wise, which is simply not true. You interpreted my question as interpretation of iterables as booleans - which is discussed in the referred question. I know about this effect but misinterpreted your words as confirming @ccl's point (which is wrong) – Marat May 05 '20 at 17:16
  • 1
    @ccl this only works because `lst1` has ones in all positions `lst2` has. If two lists were substantially different, or even their values were switched, it will be obvious `and` doesn't work this way – Marat May 05 '20 at 17:19
  • To corroborate what @Marat said, this looks cool but breaks down with a different example: `lst1 = [1, 0, 1, 1, 0]; lst2 = [1, 0, 1, 1, 1]; [i for i, _ in enumerate(lst1 and lst2) if _ == 1]` yields `[0, 2, 3, 4]`, which is wrong because both lists *do not* have the same value at the `4`th index. The correct answer in this example should be `[0, 2, 3]`. – blacksite May 05 '20 at 20:09
  • But I get what @ccl is trying to do. Perhaps numpy could save the day? `import numpy as np;[i for i, _ in enumerate(np.array(lst1) & np.array(lst2)) if _ == 1]` yields `[0, 2, 3]` – blacksite May 05 '20 at 20:11
  • Hmm you're right. I guess this is what working with Numpy all day does to you! – ccl May 06 '20 at 02:06
0

Look, simple iterate through both lists. Suppose you know length of both lists, then just do following:

lst1 =[0,1,1,1,0]
lst2 =[0,0,1,1,0]

# as we know length of the both lists, and their length are equal, 
# i'll just write length as 5, but you can have other algorhitm of finding length

list_len = 5

is_there_any_matches = False

for index in range(list_len):

    if lst1[index] == lst2[index]:

       is_there_any_matches = True
       break                           # to exit after first match

Note that this will break cycle after first match, but you can remove break, and count number of matches instead. Also, always take length of smaller list to prevent script from error with list index out of range. Have a nice time!


EDIT

I tried to make it as simple as possible, but you can use generators, or other pythonic tricks to make it shorter and more convenient use.

Nicolas Iceberg
  • 665
  • 1
  • 6
  • 17
0

You could also use NumPy's element-wise & operation, as well as argwhere for this:

>>> np.argwhere((np.array(lst1) == 1) & (np.array(lst2) == 1)).ravel()
array([2, 3])
blacksite
  • 12,086
  • 10
  • 64
  • 109