Select to view content in your preferred language

"List index out of range" error when parsing an address field.

4810
9
Jump to solution
04-11-2018 12:04 PM
AndrewThorup
Occasional Contributor

I'm getting a "list index out of range" error and I don't know why.  I'm parsing an address field to return only the street name.  The following line gives the error:

elif prop_location.strip().split()[1] == 'S' or 'W':

    return ' '.join(prop_location.strip().split()[2:-1]

According to the error log, the issue seems to be with the elif statement.  This code has worked fine for a long time, but the last several times I've run it it has given me this error.  I have checked the feature class for addresses that have a W or S with an index greater than 1, but I haven't found any.  There are some records that are blank, and others without a 'W' or 'S', but they shouldn't be a part of this if statement.  I'm not sure how to fix the code.  Here is the all the code for context (problem statement is line 12).  The error notification is added as an attachment:

def getStreetName( prop_location, Pre_Dir ):
    if prop_location is None:
        return None
    elif prop_location == ' ':
        return None
    elif " #" in prop_location:
        head, sep, tail = prop_location.partition(' #')
        if head.strip().split()[1] == 'S' or 'W':
            return ' '.join(head.strip().split()[2:-1])
        else:
            return ' '.join(head.strip().split()[1:-1])
    elif prop_location.strip().split()[1] == 'S' or 'W':
        return ' '.join(prop_location.strip().split()[2:-1])
    else:
        return ' '.join(prop_location.strip().split()[1:-1])‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
Tags (3)
0 Kudos
1 Solution

Accepted Solutions
AndrewThorup
Occasional Contributor

While looking at my code which I wrote over a year ago, I started wondering why I put 'Pre_Dir' in as a field that ocld be used.  Then I realized that I already calculated the Pre_Dir in a previous step in the model.  I substituted the problem line with the following line:

elif Pre_Dir == 'S' or 'W':
 return ' '.join(prop_location.strip().split()[2:-1])

It worked like a charm.  I obviously started out writing the code block with the intent use Pre_Dir in that fashion, but then forgot when I came to that portion of the code because I'm an airhead.  Sincere thanks to Joe, Ian, Balaji, and Joshua.  I'm still going to try out the usaddress package and let you know how it works in ModelBuilder.

View solution in original post

9 Replies
JoeBorgione
MVP Emeritus

Can you provide a value of prop_location that meets that elif conditional that is failing?

That should just about do it....
0 Kudos
AndrewThorup
Occasional Contributor

Sure, here are three different types of addresses that should be dealt with in the if statement:

1242 W 8550 S

1242 Bateman Ponds Wy

7726-7728 S 2700 W

Thanks for your help, Joe!

0 Kudos
JoeBorgione
MVP Emeritus

I run it in an IDE window and it works for me:

prop_location = '1242 W 8550 S'
>>> if prop_location.strip().split()[1] == 'S' or 'W':
     print ' '.join(prop_location.strip().split()[2:-1])
# returns

8550

Check out this discussion I started a few years ago:

A better way to parse an address?  It's a little different approach to parsing out Salt Lake Valley addresses.

Looking into my crystal ball, I see you working on the census address data for WJC....

That should just about do it....
0 Kudos
IanMurray
Honored Contributor

Looking at your screenshot, it looks like the input it failed on was appeared to be a very large numbers of spaces or tabs.  You look to have a condition to screen for a NULL value and for a single blank space, but not for multiple blank spaces or tabs. 

Perhaps your first elif should be something like this:

elif prop_location.strip() == '':

   return None

This would check for any amount of possible whitespace that could be in a field and if there are no other characters, return None.

BalajiVeera
Regular Contributor

This condition, expecting at least one space (' ') in prop_location value

> elif prop_location.strip().split()[1] == 'S' or 'W':

To avoid this error, try to skip the no space contained values by adding one more condition like

elif ' ' not in prop_location:
         return None
0 Kudos
JoshuaBixby
MVP Esteemed Contributor

Don't reinvent a wheel that has already been made, and made fairly well in this case.  Since you are only interested in parsing, and not validating, the addresses; there are several Python packages available for parsing addresses, particularly US-based addresses.  One of them being usaddress - Parserator 

>>> import usaddress
>>> 
>>> address_string = '7726-7728 S 2700 W'
>>> address_dict = {v:k for k,v in usaddress.parse(address_string)}
>>> address_dict
{'StreetNamePostDirectional': u'W', 'StreetName': u'2700', 'StreetNamePreDirectional': u'S', 'AddressNumber': u'7726-7728'}
>>> for k,v in address_dict.items():
...     print("{:40}:{}".format(k,v))
...     
StreetNamePostDirectional               :W
StreetName                              :2700
StreetNamePreDirectional                :S
AddressNumber                           :7726-7728
>>> 
AndrewThorup
Occasional Contributor

This looks like it could really be helpful.  My code is written in a 'Calulate Field' tool within a ModelBuilder model.  This may be a dumb question, but does importing work in that environment?  Can I simply import the usaddress package using the syntax above into that environment?

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

Not sure, I don't work with ModelBuilder.  I know you can import modules in the code block of the Field Calculator, which leads me to believe you can do the same in ModelBuilder.

0 Kudos
AndrewThorup
Occasional Contributor

While looking at my code which I wrote over a year ago, I started wondering why I put 'Pre_Dir' in as a field that ocld be used.  Then I realized that I already calculated the Pre_Dir in a previous step in the model.  I substituted the problem line with the following line:

elif Pre_Dir == 'S' or 'W':
 return ' '.join(prop_location.strip().split()[2:-1])

It worked like a charm.  I obviously started out writing the code block with the intent use Pre_Dir in that fashion, but then forgot when I came to that portion of the code because I'm an airhead.  Sincere thanks to Joe, Ian, Balaji, and Joshua.  I'm still going to try out the usaddress package and let you know how it works in ModelBuilder.