简体   繁体   中英

What is the most pythonic way to map two different strings, to act as one?

The problem

Imagine two services running:

Service 1 has two statuses: ACTIVE/INACTIVE

Service 2 has two statuses: RUNNING/TERMINATED

We want to do a simple status comparison as:

service1_status = get_service2_status()
service2_status = get_service2_status()

if service1_status == service2_status:
   // They match!
else:
   // They don't match!

A working solution

This is a relatively simple task of course. A working solution would be something like this:

service1_status = get_service2_status()
service2_status = get_service2_status()

if service1_status == 'ACTIVE' and service2_status == 'RUNNING':
   return "They match!"
elif service1_status == 'INACTIVE' and service2_status == 'TERMINATED':
   return "They match!"
else:
   return "They don't match!"

The problem - but more difficult

Now imagine this example a hundred different statuses for each service instead of two.

The if statement would be overwhelming. I am looking for a more elegant way to program this. eg:

matching_tuples = [('x1', 'y1'), ('x2', 'y2'), ..., ('x100', 'y100')]

service1_status = get_service2_status()
service2_status = get_service2_status()

if (service1_status, service2_status) in matching_tuples:
   return "They match!"
elif:
   return "They don't match!"

This works and is fine. I wonder though if there is a better, more pythonic and elegant way to marry two strings together and compare them.

Decide on a base-line service and map its statuses to the other:

service1_status = get_service2_status()
service2_status = get_service2_status()

mapping = {"ACTIVE": "RUNNING", "INACTIVE": "TERMINATED"}

if mapping[service1_status] == service2_status:
   return "They match!"
else:
   return "They don't match!"

In case a status of service1 might not be mapped, you can choose either to:

  1. Raise the KeyError (as above, using mapping[service1_status] ).

  2. Silence the error by using mapping.get(service1_status) instead and treat it as "no match".

  3. Catch the error and re-raise it as an informative debugging message:

     try: match = mapping[service1_status] == service2_status except KeyError: raise KeyError(f"The status {service1_status} of service1 is not mapped to any status in service2")

Depending on your actual input, you might not need to construct the dict manually:

  • If you already have something like your provided matching_tuples , you can pass that directly to the dict constructor - mapping = dict(matching_tuples) .

  • If you have two matching lists of the statuses you can do mapping = dict(zip(statuses1, statuses2)) (Note that basically matching_tuples = list(zip(statuses1, statuses2)) )

I also have to map keys from the backend and frontend.
For mapping, I usually use a dictionary you can add as many keys as you want like this.

MapService1to2 = {
    "ACTIVE": "RUNNING",
    "INACTIVE": "TERMINATED"
}

service1_status = get_service2_status()
service2_status = get_service2_status()

if MapService1to2[service1_status] == service2_status:
    print("They match")
else:
    print("They don't match")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM