git.net

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Implement C's Switch in Python 3


> >I am trying to convert a switch statement from C into Python. (why? 
> >practising).
> >
> >This is the C code.
> >
> >printf("Dated this %d", day);
> >  switch (day) {
> >    case 1: case 21: case 31:
> >        printf("st"); break;
> >    case 2: case 22:
> >        printf("nd"); break;
> >    case 3: case 23:
> >        printf("rd"); break;
> >    default: printf("th"); break;
> >
> >  }
> >  printf(" day of ");
> >
> >#Premise if the use enter an int as the date 21 for example it would print 21st. It appends the correct suffix onto a date.
> >Reading and trying to implement a function that uses a dictionary. Not 
> >sure how to supply list into it to keep it brief and with default case 
> >of 'th'.
> >
> >This is my current code.
> >
> >def f(x):
> >    return {
> >        [1, 21, 31]: "st",
> >        [2, 22]: "nd",
> >        [3, 23]: "rd",
> >    }.get(x, "th")
> >
> >
> >print(f(21))
> >
> >I have an unhashable type list. Whats the best way to go?
> 
> Skip has commented on lists being unhashable. We can elaborate on that 
> if you like.
> 
> However, even if you went to tuples (which would let you construct the 
> dict you lay out above), there is another problem.
> 
> You're looking up "x" in the dict. But the keys of the dict are not 
> integers, they are lists (or tuples) or integers, so they won't match.
> 
> You _could_ do this:
> 
>   return {
>     1: "st", 21: "st", 31: "st",
>     2: "nd", 22: "nd",
>     3: "rd", 23: "rd",
>   }.get(x, "th")
> 
> which makes distinct entries for each integer value of interest.
> 
> The conventional approach would normally be:
> 
>   if x in (1, 21, 31):
>     return "st"
>   if x in (2, 22):
>     return "nd"
>   if x in (3, 23):
>     return "rd"
>   return "th"
> 
> While this works for a small number of choices, if you had a huge dict 
> with lots of possible values you could return to your 
> dict-keyed-on-tuples approach. You would need to try each tuple in turn:
> 
>   mapping = {
>     (1, 21, 31): "st",
>     (2, 22): "nd",
>     (3, 23): "rd",
>   }
>   for key, suffix in mapping.items():
>     if x in key:
>       return suffix
>   return "th"
> 
> However, for big dictionaries (with many keys) you loose a key strength 
> of dicts: constant time lookup. You can see the above code (and the 
> earlier "if" code) are rather linear, with run time going up linearly 
> with the number of keys. You're better with the int->string single value 
> dict version.
> 
> Cheers,
> Cameron Simpson 

It seems odd with C having switch that its cleaner and more efficient than python where we are having to implement our own functions to recreate switch everytime.

Or perhaps use a 3rd party library like https://github.com/mikeckennedy/python-switch

You have both given good options, it seems there are no standard approaches in this case.

Cheers

Sayth