2

I am aware that is tests for identity and not equality of objects (eg. strings) in python. However I am curios whether in checks for equality or identity when used to check if an item is in a list / dict ?

I am unable to test this reliably as my interpreter seems to be be interning strings automatically at will (as you can see below even the is test passes implying only one copy of string was created in memory for all representations of delta):

>>> l = ['a', 'b', 'delta']
>>> if 'delta' in l:
...   print('K')
... 
K
>>> if l[2] is 'delta':
...   print('K')
... 
K
>>> if ('delt' + 'a') in l:
...   print('K')
... 
K
>>> if ('delt' + 'a') is l[2]:
...   print('K')
... 
K

backstreetrover
  • 203
  • 1
  • 11
  • 1
    The python compiler combines the string literals `'delt' + 'a'` into `'delta'` before checking for interned duplicates. Do something like `''.join('delta')` if you want a string generated at runtime that is not interned. – tdelaney Sep 11 '21 at 03:55
  • @tdelaney appreciate the comment on how interpreter checks for interned duplicates and how to avoid it! – backstreetrover Sep 11 '21 at 03:57

1 Answers1

3

According to the python documentation, for built-in container types, in tests for both identity and equality. This is the relevant line:

For container types such as list, tuple, set, frozenset, dict, or collections.deque, the expression x in y is equivalent to any(x is e or x == e for e in y).

Edit: updated the answer per juanpa.arrivillaga's comment, for non built-in container types, the behavior is implementation dependent.

Craig
  • 4,605
  • 1
  • 18
  • 28
  • 5
    Well, no. Not necessarily. This is the behavior for *built-in container data types*. The behavior for other types is up to the implementors. And it's important to note, this is meant to be an optimization – juanpa.arrivillaga Sep 11 '21 at 03:51
  • 4
    The referenced documentation is worth a read. `in` may consume an iterator. An `in` test with an open file handle will cause lines to be read until a matching line is found (or the file pointer ends up at EOF). – tdelaney Sep 11 '21 at 04:00
  • 1
    @juanpa.arrivillaga *"this is meant to be an optimization"* - Though as Raymond Hettinger [said](https://bugs.python.org/issue4296#msg75735) in a discussion about this: *The "identity implies equality" rule isn't just an optimization, it is a deep assumption that pervades the language implementation.* – no comment Sep 11 '21 at 20:03