switch-case statement for STRINGS in Python

23.6k views Asked by At

I need to do something similar to the CASE WHEN .. OR .. THEN from SQL in python for STRINGS. For example, if I say "DOG" or "CAT".. my translation is "ANIMAL".

I don't want to use IF ELIF ELIF..

The only solution that i can see is:

l = ['cat','dog', 'turttle']
d = {'animal': ['cat','dog', 'turttle']}
word = 'cat'
if word in l:
    for i, j in d.iteritems():
        if word in j:
            print i
        else:
            print word

animal

It works but it seems very ugly..

Any other solution?

THANKS!

5

There are 5 answers

4
blhsing On

For your purpose I would suggest that you go with a dict indexed by the name of the animal instead. The list l in your code would then also be redundant because it's simply the keys of this dict.

d = {
    'cat': 'animal',
    'dog': 'animal',
    'turtle': 'animal'
}
word = 'cat'
print(d.get(word, word))
0
Nihal On
d = {'animal': ['cat','dog', 'turttle']}

word = 'cat'

if word in d['animal']:
    print('animal')
3
Joe On

You can do in this way:

animal_list = ['cat','dog', 'turttle']
plant_list = ['tree', 'grass']
d = {'animal': animal_list, 'plant': plant_list}
word = 'tree'
for key, value in d.iteritems():
    if word in value:
        print key
0
cdlane On

what happened if I have 1M of words and translations?

An alternate approach is to store your data in a way that's convenient for defining it but before the main body of your code, invert the data (once) into a form that's more efficient for runtime:

by_kingdoms = {
    'animal': {'cat', 'dog', 'turtle'},
    'plant': {'rosemary', 'thyme'},
}

by_families = {}

for kingdom, families in by_kingdoms.items():
    for family in families:
        by_families[family] = kingdom

word = 'cat'

print(by_families[word])

This assumes well-structured data but you can even have overlap by making the values of the by_families dictionary lists of kingdoms in which this family might appear:

from collections import defaultdict

by_kingdoms = {
    'animal': {'cat', 'dog', 'turtle', 'bird of paradise'},
    'plant': {'rosemary', 'thyme', 'bird of paradise'},
}

by_families = defaultdict(list)

for kingdom, families in by_kingdoms.items():
    for family in families:
        by_families[family].append(kingdom)

word = 'bird of paradise'

print(by_families[word])
0
Pushkar Chintaluri On

You can use a couple of data structure based efficiencies to scale your program as follows:

  1. Use a dictionary to store the data of what classifies as "animal" or other
  2. Use a set rather than a list to group by classification. This allows for constant time lookup, regardless of how big the set is.

Something like this:

kingdom = {'animal':set(['Cat','Dog','Turtle']), 'plant':set(['Rosemary','Thyme'])}
word = 'cat'
for family in kingdom:
  if word in kingdom[family]: # here is where constant time lookup occurs
    print family
  else:
    print word

Alternately, you could define classes for "Animal" and "Plant", etc... depending on how much functionality is specific to the "Animal" or "Plant" stuff. I do subscribe to the principle of avoiding placeholder code, so would recommend not to look into classes unless you have reason to implement it.