1

I'm wondering if there's a more efficient way to do this in Python. I found a good solution in Ruby but it seems fairly specific.

Basically, I'm fetching weather condition data from an API and want to standardize their many nuanced conditions down to seven I can easily deal with them.

def standardize_weather_conditions(s):
    clear_chars = ['clear', 'sunny']
    clouds_chars = ['cloudy', 'overcast', 'fog']
    storm_chars = ['thunder']
    freezing_chars = ['ice', 'sleet', 'freezing rain', 'freezing drizzle']
    snow_chars = ['snow', 'blizzard']
    rain_chars = ['rain', 'drizzle', 'mist']

    if any_in_string(s, clear_chars):
        conditions = 'clear'
    elif any_in_string(s, clouds_chars):
        conditions = 'clouds'
    elif any_in_string(s, storm_chars):
        conditions = 'storm'
    elif any_in_string(s, freezing_chars):
        conditions = 'freezing'
    elif any_in_string(s, snow_chars):
        conditions = 'snow'
    elif any_in_string(s, wet_chars):
        conditions = 'wet'
    else:
        conditions = 'other'
    return conditions

def any_in_string(s, array):
    for e in array:
        if e in s:
            return True
    return False
Community
  • 1
  • 1
delwin
  • 830
  • 2
  • 10
  • 15

2 Answers2

2

You can define like this:

def any_in_string(s, lst):
    return any(word in s for word in lst)
JBernardo
  • 32,262
  • 10
  • 90
  • 115
2

any_in_string can be made a one-liner by doing return any([x in s for x in array])

Then you could make a dictionary mapping your description to your lists of search words:

all_chars = {'clear':clear_chars, \
             'clouds':clouds_chars, \
             'storm':storm_chars, \
             'freezing':freezing_chars, \
             'snow':snow_chars, \
             'wet':rain_chars }

for key in all_chars.keys():
     if any_in_string(s, all_chars[keys]):
         return key

return 'other'

That would help avoid the 'spaghetti-code' if-else block you have.

If you wanted to get a little more fancy, you could change the for loop above to:

conditions = [x for x in all_chars.keys() if any_in_string(s, all_chars[x])]
conditions = ' and '.join(conditions)
return conditions

This way you could get something like cloudy and wet.

kevintodisco
  • 5,061
  • 1
  • 22
  • 28
  • I really like your second suggestion, I might be able to fit that in somewhere. Also, I actually just came up with a similar solution to yours (I just pulled the `any_in_string` code out into a literal for loop instead of a call to a function). – delwin Dec 06 '12 at 02:39