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

Implement C's Switch in Python 3

On 02Feb2019 16:47, Sayth Renshaw <flebber.crue at gmail.com> wrote:
>I am trying to convert a switch statement from C into Python. (why? 
>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")
>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.

Cameron Simpson <cs at cskk.id.au>