Python: a string indexing trick

2010-02-23

Let’s say you want to extract all the lines of a file where the character at index 5 is not a space:

with open('sequences.gb') as f:
  for line in f:
    if line[5] != ' ':
      print line[:-1]

Problem: short lines. line[5] might not be a valid index. Exception.

You might consider line[5:6]. Normally this is the same as line[5], but when line is short then instead of raising an Exception it evaluates to the empty string, "".

In this case it will result in short lines being selected and printed. If the test was if line[5:6] in string.letters then it will result in short lines being rejected. But that changes the semantics of the test for the lines that are long enough. If I had written if ' '.startswith(line[5:6]) then I keep the same test semantics for long lines and I reject short lines. It’s weird and not clear though.

Sometimes this trick may be appropriate, and you may be able to tweak your test to accommodate it. Don’t let the clarity slide. There is a great deal of merit to: if len(line) > 5 and line[5] != ' '.

6 Responses to “Python: a string indexing trick”


  1. startswith is more obtuse and slower:

    python -m timeit -s “import sys” “sys.stdout.writelines(l for l in open(‘cm3.txt’) if len(l)>5 and l[5]!=’ ‘)” | grep loops
    10 loops, best of 3: 70.5 msec per loop
    padraig@crom:~$ python -m timeit -s “import sys” “sys.stdout.writelines(l for l in open(‘cm3.txt’) if not ‘ ‘.startswith(l[5:6]))” | grep loops
    10 loops, best of 3: 100 msec per loop

  2. Paul Hankin Says:

    It’s a shame lists and strings don’t have .get() like dicts. Then you could write a.get(5, ‘ ‘) != ‘ ‘.

    You can always use re.match(‘…. ‘, a) or re.match(‘.{4} ‘) but I’m doubtful that increases readability.

  3. Doug Orleans Says:

    How about this:

    if (line + '      ')[5] != ' ':

    (That’s six spaces, in case line is empty.)


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: