Efficient! I like it.
Just for fun, I tried to see if I could condense this further. Here it is!
prefixes = ['N ', 'S ', 'E ', 'W ', 'North ', 'South ', 'East ', 'West ']
with arcpy.da.UpdateCursor(table, 'STREET') as cursor:
for row in cursor:
row[0] = min([row[0][len(prefix):] if row[0].startswith(prefix) else row[0] for prefix in prefixes], key=len)
cursor.updateRow(row)
First, a list comprehension creates a list of your street name with every prefix attempted to be removed from it. Then, it turns out the min() function accepts a key argument. If you give it the built-in len, it gives you the shortest entry from that list back as a single item.
Since, by definition, every item in our generated list is either the original street name or that street name minus a prefix, the shortest possible will always* be the street name minus any applicable prefix.
*An important caveat here: "N South 5th Street" would return as "South 5th Street", which may or may not be desired. But then, that's a problem of all of the code in this thread.
Also, just to be cheeky, here it is even more condensed. I saved a whole 3 lines! But I haven't tested it. And while I think the logic and syntax are all sound, it's the height of absurdity, anyway. Please don't do this to whoever has to read your code behind you. 😛
with arcpy.da.UpdateCursor(table, 'STREET') as cursor:
[cursor.updateRow(row) for [min([row[0][len(prefix):] if row[0].startswith(prefix) else row[0] for prefix in ['N ', 'S ', 'E ', 'W ', 'North ', 'South ', 'East ', 'West ']], key=len)] in cursor]