2

I have the user select a strings of weekdays which then get stored in a list. My goal is to replace any user-selected strings with it's corresponding weekday number. My code works but it seems unnecessarily bulky. Is there a more elegant way?

selected_weekdays = ["MON", "WED", "THU", "SAT"]

for i in range(len (selected_weekdays)):
    if selected_weekdays[i] == "MON":
        selected_weekdays[i] = 0
    elif selected_weekdays[i] == "TUE":
        selected_weekdays[i] = 1
    elif selected_weekdays[i] == "WED":
        selected_weekdays[i] = 2
    elif selected_weekdays[i] == "THU":
        selected_weekdays[i] = 3
    elif selected_weekdays[i] == "FRI":
        selected_weekdays[i] = 4
    elif selected_weekdays[i] == "SAT":
        selected_weekdays[i] = 5
    elif selected_weekdays[i] == "SUN":
        selected_weekdays[i] = 6
    else:
        pass

print(selected_weekdays)

Correct output:

[0, 2, 3, 5]
martineau
  • 119,623
  • 25
  • 170
  • 301
quadratecode
  • 396
  • 1
  • 2
  • 12
  • 2
    you could map them in a dict `{"MON": 0, "TUE": 1 ...}` and read the keys from it; it's also largely better not to modify a structure while you're iterating over it – ti7 Dec 02 '21 at 15:20

4 Answers4

2

Using a dictionary with a list comprehension:

days = {'MON': 0, 'TUE': 1, 'WED': 2, 'THU': 3, 'FRI': 4, 'SAT': 5, 'SUN': 6}
selected_weekdays = ["MON", "WED", "THU", "SAT"]
output = [days[x] for x in selected_weekdays]
print(output)  # [0, 2, 3, 5]
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
2

You can avoid some extra work by generating your dictionary mapping

it's also better to avoid modifying a structure you're also iterating over for a variety of reasons
See Modifying list while iterating

The dictionary .get() method will choose a default choice (weekday in your original case, though you may want to change this such that it's one of

  • the unlisted weekday (this is what your code currently does, so I kept the results the same)
  • an Exception (KeyError from directly indexing [] .. you may want this to highlight errors)
  • None (essentially throws out bad values and is easy to filter in a next step)
# dictionary expression
weekday_mapping = {day: index for index, day in enumerate((
    "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"))}

selected_weekdays = ["MON", "WED", "THU", "SAT"]
results = []
for weekday in selected_weekdays:
    results.append(weekday_mapping.get(weekday, weekday))
>>> results
[0, 2, 3, 5]
>>> selected_weekdays = ["MON", "WED", "THU", "FakeDay", "SAT"]
...
>>> results
[0, 2, 3, 'FakeDay', 5]
ti7
  • 16,375
  • 6
  • 40
  • 68
1

You could use a dictionary:

day_number = {"MON": 0, "TUE": 1, "WED": 2, "THU": 3, "FRI": 4, "SAT": 5, "SUN": 6}

selected_weekdays = ["MON", "WED", "THU", "SAT"]

for i in range(len(selected_weekdays)):
    selected_weekdays[i] = day_number[selected_weekdays[i]]

print(selected_weekdays)

Instead of the for-loop, you could use

selected_weekdays = [day_number[d] for d in selected_weekdays]
  • Thank you for taking the time to answer. This returns an error for me: `TypeError: 'dict' object is not callable`. I think square brackets are needed, e.g.: `selected_weekdays[i] = day_number[selected_weekdays[i]]` / `selected_weekdays = [day_number[d] for d in selected_weekdays]` – quadratecode Dec 02 '21 at 15:41
  • 1
    right, I corrected – GuglielmoSanchini Dec 02 '21 at 15:55
1

One method is to use a list, and have the values be the indices of the list:

weekdays_list = ["MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"]
selected_weekdays = ["MON", "WED", "THU", "SAT"]
selected_weekdays_numbered = [weekdays_list.index(i) for i in selected_weekdays]
print(selected_weekdays_numbered)

Output:

[0, 2, 3, 5]
Erik McKelvey
  • 1,650
  • 1
  • 12
  • 23