Reputation: 141
in
operator in Python is a membership operator that tests for membership in a sequence.
Description of in
operator
Evaluates to true if it finds a variable in the specified sequence and false otherwise.
Now consider the code:
>>>s = 'HELLO'
>>>char = 'M'
>>>char in s
False
>>>for char in s:
.... print(char)
H
E
L
L
O
Please correct me here:
I think the statement for char in s
should check for 'M'
in 'HELLO'
which should be evaluated to False
and the loop should be terminated. But here, instead of checking for the membership, it is assigning every character to the variable char
and thus the loop is printing the every character.
My question is, how in
operator can be used other than checking the membership?
Upvotes: 2
Views: 1167
Reputation: 16720
The in
keyword is used in two different contexts:
The first, as you said, checks if something belongs to a sequence, by calling that sequence's __contains__
. When using this syntax, a boolean value is returned.
x = 1
l = [0, 1, 2]
if x in l:
print("x is in l")
else:
print("x is not in l")
> x is in l
Since in
looks for the __contains__
method, x in seq
is valid as long as seq
implements a __contains__
method. You can implement this, even though it does not make logical sense, regarding the concept of membership.
class Foo:
def __contains__(self, x):
return x == 12
f = Foo()
if 12 in f:
print("12 is in f")
> 12 is in f
The second is actually more often used. According to an iteration protocol, it enumerates the elements of an iterable object, so that actions can be performed on them.
You can iterate over a list:
l = [0, 1, 2]
for x in l:
print(x)
> 0 > 1 > 2
Over a string:
s = "hello"
for c in s:
print(c)
> h > e > l > l > o
And over any object implementing the __iter__
method, as long as the latter returns an object that implements the __next__
method.
The following example is a basic (not to say "poor") range
-like class, whose you can iterate over the instances.
class Bar:
def __init__(self, first, last):
self.first = first
self.last = last
self.current = first
def __iter__(self):
return self
def __next__(self):
if self.current == self.last:
raise StopIteration
result = self.current
self.current += 1
return result
b = Bar(0, 5)
for i in b:
print(i)
> 0 > 1 > 2 > 3 > 4
A lot of native types are iterable: dictionaries, ranges, sets...
Semantically speaking, it makes sense to use the same in
word for both contexts. "Is this thing in that stuff?" is a valid question, as long as "stuff" is a collection, which is capable of containing things. Henceforth, "do this for every thing in that stuff" seems pretty natural.
Hence the use of "in" for both contexts.
This is however quite a simplification of the reality, which is actually more vast. I invite you to read the documentation, and for an in-depth understanding of the in
keyword, read Python's grammar.
Upvotes: 6
Reputation: 641
The main thing you need to think here is that the keyword in
if you use it in a for
loop then it'll redefine char or every line in the loop.
so to test every character individually in a loop you'd need:
s = 'HELLO'
char = 'M'
for chr in s:
if char in chr:
print chr
but that's kind of pointless. You might as well use if char=chr
But you can test for characters in list elements like this so:
s = ['HELLO', 'MIKE', 'BOB']
char = 'M'
for word in s:
if char in word:
print word
would test every list element for the presence of "M"
Upvotes: 0
Reputation: 116
any object that has the __contains__() method can use the "in" operator. by using the dir() function or the hasattr() function you can check if you can use the "in" operator on that object
>>>dir(hw)
[...,__contains__,...]
>>>hasattr(hw,"__contains__")
True
Upvotes: 0