Logo
RSS Feed

Python3 And The Deathly Hallows

Created: 23.09.2020

Beautiful Python 🐍, which has so many small blocks of code that ease the task so much! Here is my collection of these building blocks that can be applied to many every day challenges. I am sure some or even all of them might be present in other languages as well, but I don’t know other languages equally well, so, pardon my Python 😄

Challenge

Imagine a task. We are given an array (which is actually a list) of dictionaries. Something like a score log (may be a tiny NoSQL DB). For example:

candidates = [
  {"name": "Matt",
   "age": 17,
   "score": 1
  },
  {"name": "Matt",
   "age": 17,
   "score": 1
  },
  {"name": "Mark",
   "age": 90,
   "score": 1
  },
  {"name": "Mark",
   "age": 90,
   "score": 1
  },  
  {"name": "Matt",
   "age": 17,
   "score": 1
  },
  {"name": "Lucie",
   "age": 19,
   "score": 1
  },
  {"name": "Matt",
   "age": 17,
   "score": 1
  },
  {"name": "Matt",
   "age": 17,
   "score": 1
  },
   {"name": "Lucie",
   "age": 19,
   "score": 1
  },
   {"name": "Lucie",
   "age": 19,
   "score": 1
  },
   {"name": "Lucie",
   "age": 19,
   "score": 1
  },
  {"name": "Matt",
   "age": 17,
   "score": 1
  },
  {"name": "Michael",
   "age": 19,
   "score": 1
  },
  {"name": "Matt",
   "age": 17,
   "score": 1
  },
  {"name": "Linda",
   "age": 24,
   "score": 1
  },
  {"name": "Linda",
   "age": 24,
   "score": 1
  },
  {"name": "Michael",
   "age": 19,
   "score": 1
  },
  {"name": "Michael",
   "age": 19,
   "score": 1
  },
  {"name": "Linda",
   "age": 24,
   "score": 1
  },
  {"name": "Mark",
   "age": 90,
   "score": 1
  }  
]

Each dictionary inside the list contains some information about the compeititor (name and age) and the score, that they have earned. Your task is to find top five champions in the above score table. Well, the easiest approach is to first iterate through this list, put each name in a dictionary, and then whenever we encounter the same competitor, we increment the value. In the end we would have a hash table of competitors with their total scores. To get the top 3 we would sort it and get the first 3 values. Let’s see it coded:

scores_hashtable = {}
for candidate in candidates:
    if candidate["name"] in scores_hashtable:
        scores_hashtable[candidate["name"]] += 1
    else:
        scores_hashtable[candidate["name"]] = 1

sorted_scores_table = sorted(scores_hashtable.items(), key=lambda x: x[1], reverse=True)

i=0
for chap in sorted_scores_table:
    if i >= 3:
        break
    print("The champion is {} and their score is {}".format(chap[0], chap[1]))
    i += 1

So, we have 5 champions but we need only three of them to be printed. The above is the most straightforward solution. And I have not implemented sorting for a dictionary myself. If.I had, I would get a much bigger code. Because of the sorted the time complexity is going to be O(nlogn).

Python has this beautiful thing: Counter. It’s doing pretty much the same what I was doing when filling scores_hashtable in. Let’s substitute this part of the code using Counter:

scores_hashtable = Counter([x["name"] for x in scores])

Now the code has reduced twice in size:

scores_hashtable = Counter([x["name"] for x in candidates])
sorted_scores_table = sorted(scores_hashtable.items(), key=lambda x: x[1], reverse=True)

i=0
for chap in sorted_scores_table:
    if i >= 3:
        break
    print("The champion is {} and their score is {}".format(chap[0], chap[1]))
    i += 1

🗒 #todo: about sorted()

Also, this Counter has a useful method most_common. This method takes an integer argument to determine, how much to print. For example, to print top 3 candidates out of 5, we would use the following:

print(scores_hashtable.most_common(3)) 

As the result, we are having the following code instead of the original solution:

scores_hashtable = Counter([x["name"] for x in scores])
print(scores_hashtable.most_common(3)) 

Elegant, isn’t it?

gettyimages-sb10066601b-001-1024x1024

I am planning on expnading this article and writing a separate sort of FM for python.

References