1

Is it correct to check for empty strings using is in Python? It does identity checking, while == tests equality.

Consider the following (the idea of using join is borrowed from this answer):

>>> ne1 = "aaa"
>>> ne2 = "".join('a' for _ in range(3))
>>> ne1 == ne2
True
>>> ne1 is ne2
False
>>>

so here is works as one may expect. Now take a look at this code:

>>> e1 = ""
>>> e2 = "aaa".replace("a", "")
>>> e3 = "" * 2
>>> e4 = "bbb".join(range(0))
>>> e1, e2, e3, e4
('', '', '', '')
>>> e1 is e2
True
>>> e1 is e3
True
>>> e1 is e4
True
>>> id(e1), id(e2), id(e3), id(e4)
(35963168, 35963168, 35963168, 35963168) # why?
Community
  • 1
  • 1
khachik
  • 28,112
  • 9
  • 59
  • 94

4 Answers4

15

The correct way to check for an empty string is to just do:

if yourstring:
   print "string is not empty"

e.g. bool(yourstring) will be False if your string is empty. The reason your example works is because CPython caches certain strings and integers and reuses them for efficiency. It's an implementation detail and shouldn't be relied upon.

mgilson
  • 300,191
  • 65
  • 633
  • 696
  • the question was not about what is the correct way to check for an empty string. It was about is that correct to use `is` to check for empty strings. Hope it is clear. – khachik Sep 04 '12 at 12:32
  • 1
    @khachik: Yes, it was clear, and by giving you the proper way mgilson is implicitly saying that using `is` is *not* the correct way. – Martijn Pieters Sep 04 '12 at 12:34
  • How about `if not yourstring:` – Burhan Khalid Sep 04 '12 at 12:35
  • @MartijnPieters thank you for the interpretation. What about why it works for empty strings? – khachik Sep 04 '12 at 12:37
  • @MartijnPieters -- Thanks for clarifying that :). Yes, I was saying that using `is` is *not the correct way*. – mgilson Sep 04 '12 at 12:37
  • 1
    @khachik: The part where mgilson says "The reason your example works" isn't clear to you? CPython interns (creates singletons for) small python strings for efficiency, but that is an implementation detail of CPython. – Martijn Pieters Sep 04 '12 at 12:39
  • 4
    This isn't just an academic concern. PyPy doesn't behave like CPython here: `a = ''; b = 'a'[:0]; a is b` is False. Actually, whether `''` is `''` can even depend in the PyPy console on whether you put everything on one line or not: `a = ''; b = ''; a is b` gives `True` all on one line and `False` spread out over three. – DSM Sep 04 '12 at 12:43
  • I'm would like to improve this answer if possible. Feel free to leave a comment about how I could make it better. Thanks! – mgilson Sep 04 '12 at 14:42
8

A Python implementation may choose to intern small strings (well, it may choose to intern anything immutable, really); Cpython does so.

You should never rely on this behavior. If you want to check if a string is the empty string, always use mystring == "".

If you're sure the object you're checking is always a string, you can also evaluate it in a boolean context (e.g., if mystring:), but keep in mind that this won't distinguish the empty string from 0, False, or None.

Wooble
  • 87,717
  • 12
  • 108
  • 131
  • 2
    It should be pointed out that `mystring == ""` does not guarantee that you have an empty string either (consider the case where you have a class which overrides `__eq__`). One thing about python is that it *(typically) shouldn't matter* whether you have a string or not. If you really want to make sure you have a string (and that it is empty), maybe `"" == mystring` would work (since this uses `__eq__` on `""` instead of `__eq__`) or even `isinstance(mystring,basestring) and mystring == ''` to be more explicit. – mgilson Sep 04 '12 at 12:54
  • @mgilson even those aren't guaranteed to work - if you really, *really* care that `mystring` is *exactly* `''`, and not, eg, an empty subtype-of-string, you'd need `mystring == '' and type(mystring) == str` (since `str.__eq__(mystring, '')` will return `NotImplemented`). But then `type(mystring)`'s metaclass could override `__eq__`, so we try `mystring == '' and type.__eq__(type(mystring), str)`. But then *that* returns `NotImplemented`... and hopefully stop short of dropping to C, and revert to `if not mystring:`. – lvc Sep 04 '12 at 14:00
  • 1
    @lvc -- Yeah, I suppose maybe I should have placed more emphasis on the sentence in the middle : "In python, it shouldn't matter whether you have a string or not". Shame on you if using `0` instead of `""` breaks your code :^). – mgilson Sep 04 '12 at 14:05
1

The best way to check for an empty sequence (string, list, ...) is:

if variable:
  pass

from Truth Value Testing

The following values are considered false:

any empty sequence, for example, '', (), []

Please also read the documentation regarding comparison:

  • is compares the identity
  • == compares the equality depending on the type

Strings are compared lexicographically using the numeric equivalents (the result of the built-in function ord()) of their characters. Unicode and 8-bit strings are fully interoperable in this behavior

Andre Bossard
  • 6,191
  • 34
  • 52
0

The "is" operator returns true if you are pointing to the same object, as python try to not repeat the strings (it checks if this strings already exists in memory) it will return the same object.

I wouldn't use "is" to compare strings, it's like the "==" operator in Java, it usualy works, but maybe you can get new instances and it will return false, I prefer using == that it will call the method eq and returns True if both strings are equals, even if they are different objects.