How to use Python 'in' operator to check my list/tuple contains each of the integers 0, 1, 2?
Asked Answered
S

5

6

How do I use the Python in operator to check my list/tuple sltn contains each of the integers 0, 1, and 2?

I tried the following, why are they both wrong:

# Approach 1
if ("0","1","2") in sltn:
     kwd1 = True

# Approach 2
if any(item in sltn for item in ("0", "1", "2")):
     kwd1 = True

Update: why did I have to convert ("0", "1", "2") into either the tuple (1, 2, 3)? or the list [1, 2, 3]?

Schema answered 9/2, 2016 at 21:7 Comment(8)
Needs editing cannot understandRighthander
But ("0","1","2") isn't in [0, 1, 2]...Volkan
1. Items being in a list is not the same as the tuple of those items being in the list. 2. strings are not numbers.Scamander
if all(x in sltn for x in ("0","1","2")): Anarthria
Possible duplicate of In Python how to check all elements in a tuple are in anotherScissors
Regarding your edit: you forgot the conversion to integer, see my answer.Choker
Other comments have pointed this out, but could this be a typo: [0, 1, 2]? Did you mean to type ["0", "1", "2"]. If slnt is [0, 1, 2], you need to change if any(item in sltn for item in ("0", "1", "2")): to if any(item in sltn for item in (0, 1, 2)): since a list/tuple of ints is not the same as one of strings.Hobbie
You're confusing integers 0,1,2 with strings "0","1","2". You're also confusing tuples (...) with lists [...], but here that doesn't matter, list and tuple are both collections and support in operator. (But please don't call them arrays, those are different again). You're also confusing if x in y with if y in x and all(xx in y for xx in x) and that does matter hugely.Presentment
C
8
if ("0","1","2") in sltn

You are trying to check whether the sltn list contains the tuple ("0","1","2"), which it does not. (It contains 3 integers)

But you can get it done using #all() :

sltn = [1, 2, 3] # list
tab = ("1", "2", "3") # tuple

print(all(int(el) in sltn for el in tab)) # True
Cavorilievo answered 9/2, 2016 at 21:9 Comment(3)
How do I test if it has those units ? Sorry, I am not very advanced at python.Schema
to test for every member: inside = True;for i in ("0","1","2"): if(i in sltn): continue;else: inside = False;break;Enlightenment
I'm really surprised that everyone has come up with this solution. Iteration for comparison is not valid. It is a very bad practice. What if there were a million rows in the list? The user should sit and wait for half hour?Economic
C
22

Using the in keyword is a shorthand for calling an object's __contains__ method.

>>> a = [1, 2, 3]
>>> 2 in a
True
>>> a.__contains__(2)
True

Thus, ("0","1","2") in [0, 1, 2] asks whether the tuple ("0", "1", "2") is contained in the list [0, 1, 2]. The answer to this question if False. To be True, you would have to have a list like this:

>>> a = [1, 2, 3, ("0","1","2")]
>>> ("0","1","2") in a
True

Please also note that the elements of your tuple are strings. You probably want to check whether any or all of the elements in your tuple - after converting these elements to integers - are contained in your list.

To check whether all elements of the tuple (as integers) are contained in the list, use

>>> sltn = [1, 2, 3]
>>> t = ("0", "2", "3")
>>> set(map(int, t)).issubset(sltn)
False

To check whether any element of the tuple (as integer) is contained in the list, you can use

>>> sltn_set = set(sltn)
>>> any(int(x) in sltn_set for x in t)
True

and make use of the lazy evaluation any performs.

Of course, if your tuple contains strings for no particular reason, just use
(1, 2, 3) and omit the conversion to int.

Choker answered 9/2, 2016 at 21:23 Comment(11)
In fact this is the only answer about the in operator. +1.Enlightenment
You should use issubset or issuperset as show in my answer here instead of using a for loop. set(map(int, t)).issubset(sltn)Scissors
Iteration for comparison is not a valid solution. It would take half an hour if the list contained a million entries!Economic
@PouriaHadjibagheri and user3100115 you are right, updated.Choker
@timgeb, although clearly each class can define its own __contains__, it seems a bit inconsistent that 'abc'.__contains__('ab') is True but [1,2,3].__contains__([1,2]) is False (and similarly for tuples). Is there a rationale for this disparity?Comptometer
@Comptometer for strings, __contains__ answers the substring-question. For lists, __contains__ answers whether its argument is an element of the list. [1, 2] is not an element of the list [1, 2, 3]. ([1, 2] would be an element of the list [[1, 2], 3], for example.)Choker
@timgeb, understood, but still seems asymmetrical, like ab should also be an element of ['ab','c']Comptometer
@Comptometer 'ab' in ['ab', 'c'] is True.Choker
@timgeb, my fault, I considered the wrong branch. It's asymmetrical b/c 'ab' in 'ab'+'c' is True while the analogous [1,2] in [1,2]+[3] is FalseComptometer
@Comptometer Strings have different use cases than lists. Having their methods behave exactly the same would be a very foolish kind of consistency. You can call the design asymmetrical, but you should be glad it is.Choker
@timgeb, understood, but they are both isinstance(arg, collections.Iterable) which is how some problems arise.Comptometer
C
8
if ("0","1","2") in sltn

You are trying to check whether the sltn list contains the tuple ("0","1","2"), which it does not. (It contains 3 integers)

But you can get it done using #all() :

sltn = [1, 2, 3] # list
tab = ("1", "2", "3") # tuple

print(all(int(el) in sltn for el in tab)) # True
Cavorilievo answered 9/2, 2016 at 21:9 Comment(3)
How do I test if it has those units ? Sorry, I am not very advanced at python.Schema
to test for every member: inside = True;for i in ("0","1","2"): if(i in sltn): continue;else: inside = False;break;Enlightenment
I'm really surprised that everyone has come up with this solution. Iteration for comparison is not valid. It is a very bad practice. What if there were a million rows in the list? The user should sit and wait for half hour?Economic
A
1

To check whether your sequence contains all of the elements you want to check, you can use a generator comprehension in a call to all:

if all(item in sltn for item in ("0", "1", "2")):
    ...

If you're fine with either of them being inside the list, you can use any instead:

if any(item in sltn for item in ("0", "1", "2")):
    ...
Anarthria answered 9/2, 2016 at 21:13 Comment(4)
@Schema ... and the result is that none of "0", "1", or "2" is an element of sltn because sltn is a list of the integers 0, 1, and 2 - it does not contain any strings. This answer is correct, but I thought that I'd point that out to the OP in case they try it out and don't get the expected resultDecimeter
Seriously? You wanna iterate through the entire list every time? That's very inefficient. What if the list contained a million entries?Economic
Membership tests are linear in lists, correct. If there are a million entries, they should probably use a set instead.Anarthria
They should use set in the beginning. It's a bad practice to use iterations for comparison, regardless of the length. Now I understand that people may very well do that, but that doesn't make it right!Economic
E
0

In case you don't want waste time and iterate through all the data in your list, as widely suggested around here, you can do as follows:

a = ['1', '2', '3']
b = ['4', '3', '5']

test = set(a) & set(b)
if test:
    print('Found it. Here it is: ', test)

Of course, you can do if set(a) & set(b). I didn't do that for demonstration purposes. Note that you shouldn't replace & with and. They are two substantially different operators.

The above code displays:

Found it. Here it is:  {'3'}
Economic answered 9/2, 2016 at 21:57 Comment(0)
C
0

Adding another variation, Prints the index of different values and the values themselves.

tuple1 = (1, 2, 3, 4, 5, 6)
list1 = [1, 2, 3, 0, 5, 6]

print(type(tuple1))
print(type(list1))

for a, b in zip(list1, tuple1):
    if a != b:
       print(f'index {list1.index(a)} in list1 is different from index {tuple1.index(b)} in tuple1')
       
S1 = set(list1)
S2 = set(tuple1)
difference = list(S1.symmetric_difference(S2))
print(f'The values of symmetric difference between two sets is {difference}')

produces,

<class 'tuple'>
<class 'list'>
index 3 in list1 is different from index 3 in tuple1
The values of symmetric difference between two sets is [0, 4]

[Program finished]
Countersign answered 28/2, 2021 at 7:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.