Domanda

I am trying to check if a word has a trailing semicolon. I have the position of the word within a long string, and I want to check if the character at the position start of word + length of word is a :. It can be that the word is the last word in the string, and therefore trying to get the next char will raise an IndexException

I have three ideas:

1) Check that we are not at the end of the string, and then check that it is not semicolon

semicolon_pos = pos_word + len(word) # Possible position
if semicolon_pos < len(long_string) and long_string[semicolon_pos] == ':':
    # do something...
else:
    # do something else

Not what it is normally considered pythonic

2) Try-except the semicolon extraction and the equality for the semicolon

semicolon_pos = pos_word + len(word) # Possible position
try:
   if long_string[semicolon_pos] == ':':
      # Do something
   else:
      # do something else (which is the same as in the except clause)

except IndexError:
    # do something else

Looks a little bit weird, to extract and then nested. And I have to do a little trick to avoid the code duplication

3) Try-except the semicolon extraction and an assertion to make sure it is a semicolon

semicolon_pos = pos_word + len(word) # Possible position
try:
    assert long_string[semicolon_pos] == ':'
    # do something
except (IndexError, AssertionError):
    # do something else

Structure is flatter and it is easily read, but I have the feeling that is abusing exceptions usage.

What do the python folks say? thanks in advance.

È stato utile?

Soluzione 2

The simplest way is just to use a slice as a subscript. Slices don't throw IndexError:

semicolon_pos = pos_word + len(word) # Possible position
if long_string[semicolon_pos:semicolon_pos+1] == ':':
   # Do something
else:
   # do something else 

Altri suggerimenti

Definitely a misuse of assertions. Reason: assertions aren't even executed when the code is run with the -O flag.

The recommended way to use assertions is to check for "impossible" conditions resulting from a mistake in the algorithm (post-conditions). For pre-conditions and program logic, one should use ordinary exceptions.

(string[index] if index < len(string) else None) == ':'

I think it is easier this way:

#considering mylongstring contains the word
#+1 for the possible colon
mylongstring[:pos_word + len(word) + 1].endswith(':')

Or, if the long string is very long you don't want to copy too much:

mylongstring[pos_word:pos_word + len(word) + 1][-1] == ':'
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top