-3

Why is the code below returning FALSE in Python? Shouldn't it be TRUE, because b already includes "T".

a = ["T"]
b = ["H", "T"]
a in b
False
Kolom
  • 217
  • 1
  • 11
  • 9
    `"T"` may be an element of `b`, but `["T"]` isn't. – user2357112 Jul 31 '20 at 21:59
  • 3
    Because `b` isn't `["H",["T"]]`? Just because your refrigerator has an egg in it, it doesn't automatically mean that it has an egg sitting in a carton inside of it. – John Coleman Jul 31 '20 at 21:59
  • That just follows from the definition. There is no element equal to `a` in `b`, which is that definition basically. What you are looking for is a subset-like containment. – Ulrich Eckhardt Jul 31 '20 at 22:00
  • 1
    because `['T']` is not in `["H", "T"]`... none of the elements of the latter are equal to the former... note `["T"] != "T"` – juanpa.arrivillaga Jul 31 '20 at 22:00
  • 2
    "Shouldn't it be TRUE?" No. What makes you think it should? – MisterMiyagi Jul 31 '20 at 22:02
  • Why are you closing the question? There are quite good answers below, which may be helpful for some else, as well. JC. – Kolom Jul 31 '20 at 22:16
  • Cannot speak for others, but: I CV'd because the code shows the expected, documented behaviour. There is no reason to assume it should show any other behaviour, and the question does not clarify why the author does. As such, the expectation is "not reproducible". Answers are required to guess why this behaviour is surprising, and speculate what constitutes a sufficient explanation why something behaves as it should. – MisterMiyagi Jul 31 '20 at 22:22
  • @MisterMiyagi because something is documented, does not mean everybody understands how it works. That's why we are asking questions and more knowledgable users answer them. Otherwise, you can tag 99 % of the questions on this site as documented behavior. – Kolom Jul 31 '20 at 22:28
  • 2
    Again, it's not clear what constitutes a sufficient explanation of "why". Did you expect subsequence membership? Did you expect subset membership? Did you confuse ``["T"]`` with ``"T"``? These all lead to different reasons why one would erroneously suspect a different result. Are you wondering why lists behave this way? Is that from a logical point ("it's most common") or from a practical point ("it's efficient")? All of these are not clarified, and must be guessed to answer. Note that you can [edit] the question to clarify what you are asking, and it gets automatically reviewed for reopening. – MisterMiyagi Jul 31 '20 at 22:37
  • you are an interesting person, that's the least I can say. – Kolom Jul 31 '20 at 22:42
  • @Kolom MisterMiyagi makes a good point. Please [edit] your question to explain why you are surpised by the results. Why do you expect the result to be True? – Code-Apprentice Aug 01 '20 at 01:40
  • 2
    @Kolom You say "because something is documented, does not mean everybody understands how it works" which is true. But the assumption here is that you read the documentation and if you still don't understand then ask a more fully fledged question that includes your research. – Code-Apprentice Aug 01 '20 at 01:42

5 Answers5

7

The in operator behaves differently with strings and with lists. With strings, it's a substring operator: "bc" in "abcd" is true. With lists, it's a membership operator: 2 in [1,2,3,4] is true, but [2,3] in [1,2,3,4] is false since [2,3] is not an element of the list [1,2,3,4].

Think of in as being primarily a membership test. Strings are a special case because an element of a string is a character, but Python represents characters as strings of length 1. So a member of a string (a character) is a also substring of that string. For strings, in is a membership test if the left operand is a string of length 1. In other words, when a is a string of length 1 and b is a string, a in b tests whether a is a member of b, but under those hypotheses this is equivalent to testing whether a is a substring of b. This is extended to a substring test for arbitrary left operands (a empty or longer than a single character).

If you want to test whether a list is a sublist of another list, see Check for presence of a sliced list in Python

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
4

I think you believe that the test should return True because all items in a are also in b, in which case you're really looking to test if a is a subset of b, and you should thus make a and b sets and use the <= operator for the test instead:

>>> a = {"T"}
>>> b = {"H", "T"}
>>> a <= b
True
blhsing
  • 91,368
  • 6
  • 71
  • 106
  • "You're thinking of `in` in terms of a set operation here" seems ambiguous to me. Both "is an element of" and "is a subset of" are set operations. As you explain futher, the OP is probably expecting "is a subset of" when this is really "is an element of". – Code-Apprentice Jul 31 '20 at 22:05
  • Or they're thinking about string operations, or subsequences, or ... – MisterMiyagi Jul 31 '20 at 22:08
  • 1
    I've reworded my answer then. – blhsing Jul 31 '20 at 22:09
  • 1
    I think the thought behind your original answer was on the right track. The current wording is much more accurate. – Code-Apprentice Aug 01 '20 at 01:38
3

a in b returns False because ["T"] is not an element of ["H", "T"]. Compare:

>>> a = ["T"]
>>> b = ["H", "T"]
>>> a in b
False
>>> c = "T"
>>> c in b
True
>>> d = ["H", ["T"]]
>>> a in d
True
>>> 
Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
2

a is ["T"]. b contains "T", but it does NOT contain ["T"].

M-Chen-3
  • 2,036
  • 5
  • 13
  • 34
2

You might be thinking of "T" in b, when expecting True to be returned. Note that b is a list of strings, and a (ie ["T"]) is a list (only with one element:"T"), so a in b is necessarily False.

zabop
  • 6,750
  • 3
  • 39
  • 84