Another challenge I have enjoyed solving is finding all the unique email addresses. I have just copied and pasted the description from LeetCode, as it does a better job explaining the problem than me.
Every email consists of a local name and a domain name, separated by the @ sign.
For example, in
alice is the local name, and
leetcode.com is the domain name.
Besides lowercase letters, these emails may contain
If you add periods (
'.') between some characters in the local name part of an email address, mail sent there will be forwarded to the same address without dots in the local name. For example,
"firstname.lastname@example.org" forward to the same email address. (Note that this rule does not apply for domain names.)
If you add a plus (
'+') in the local name, everything after the first plus sign will be ignored. This allows certain emails to be filtered, for example
email@example.com will be forwarded to
firstname.lastname@example.org. (Again, this rule does not apply for domain names.)
It is possible to use both of these rules at the same time.
Given a list of
emails, we send one email to each address in the list. How many different addresses actually receive mails?
As always, I am explaining what I do at every step, and then I post the whole solution at the end.
Firstly, I am creating a new list that will hold all the unique email addresses. This variable will be used to return the length of the list, which is the number of individual addresses that receive the emails.
uniqueEmails = 
The next step is to iterate over all the given emails and take each email individually. From the description we know that each email address is made from a local name and a domain name. Thus, I split each email address in two parts: local name and domain name.
for email in emails: localname, domainame = email.split("@")
By splitting each email address in two halves, I can check whether the localname contains the + (plus) sign. If it does, I am splitting again the local name into two parts: one containing the string before the plus sign, and one containing the string after the plus sign.
if("+" in localname): localname = localname.split("+")
Because the localname is split into two parts, I can ignore the part after the plus sign by using only the part before the plus sign localname. From the description, I also know that the . (dot) does not change the email address. For example, catalins.tech is the same as catalinstech. Thus, I am removing the dot (.) with the help of the replace method.
localname = localname.replace('.', '') newEmail = localname + "@" + domainame
After removing the string after the plus sign and removing the dot, I create a new email address by appending the localname to the domainname. However, there is one last step before finishing. To avoid duplicates, I am checking if the email address is not already in the list. If it is not, add it to the list. All that is left is to return the length of the list. Since it only contains unique email addresses, the length of the list represents the email addresses.
The full final solution is below.
class Solution(object): def numUniqueEmails(self, emails): """ :type emails: List[str] :rtype: int """ ''' email@example.com is the same as firstname.lastname@example.org email@example.com is the same as firstname.lastname@example.org ''' uniqueEmails =  for email in emails: localname, domainame = email.split("@") if("+" in localname): localname = localname.split("+") localname = localname.replace('.', '') newEmail = localname + "@" + domainame if(newEmail not in uniqueEmails): uniqueEmails.append(newEmail) return len(uniqueEmails)
The statistics of the solutions: