Python replace in list

I have a list with different email formatting, which I want to unify all in one. There are 2 types of email:

name.surname@dom
name.surname.extern@dom

My program allows the user to input emails, and to not have to enter "@dom" all the time (it's always the same one), what I've done is allowing the user to write name.surname or name.surname.e and then the script replaces those usernames with @dom or .extern@dom The problem rises when I have all the mails in different formats stores in a list, and I want them to be filled to standards, so that if I have

["john.doe@dom", "john2.doe", "john3.doe.e","john4.doe.extern@dom"]

it all ends up looking like this

["john.doe@dom", "john2.doe@dom", "john3.doe.extern@dom","john4.doe.extern@dom"]

I have tried with list comprehensions, but all I got was three concatenations:

["%s.xtern@dom" % x for x in mails if x[-2:] == ".e"] +
["%s@dom" %x for x in mails if "@dom not in mails" and x[-2:] != ".e"] + 
[x for x in mails if "@dom" in x]

I'm sure there's a better way that does not require me to do 3 list comprehensions and that does not require me to do

for i,v in enumerate(mails):
    if "@dom" not in v:
        mails[i] = "%s@dom" % v
    etc.

5 answers

  • answered 2018-11-08 08:06 Green Cell

    You can use a string's endswith() method to determine what you need to do with the input:

    mails = ["john.doe@dom", "john2.doe", "john3.doe.e","john4.doe.extern@dom"]
    
    final_mails = []
    
    for mail in mails:
        if mail.endswith("@dom"):
            # Use as-is if it ends with @dom.
            final_mails.append(mail)
        elif mail.endswith(".e"):
            # Replace to extern@dom if it ends with .e
            final_mails.append(mail.replace(".e", ".extern@dom"))
        else:
            # Add @dom on all other cases
            final_mails.append("{}@dom".format(mail))
    
    print final_mails
    
    # Result: ['john.doe@dom', 'john2.doe@dom', 'john3.doe.extern@dom', 'john4.doe.extern@dom']
    

    It might need more thorough checks to not accept things like @dom right in the middle of the name and whatnot. Hope that helps you out though!

    Edit: Just for fun, if you insist on a list comprehension:

    mails = ["john.doe@dom", "john2.doe", "john3.doe.e","john4.doe.extern@dom"]
    
    final_mails = ["{}@dom".format((mail.replace(".e", ".extern@dom") 
                   if mail.endswith(".e") else mail).rstrip("@dom")) 
                   for mail in mails]
    
    print final_mails
    
    # Result: ['john.doe@dom', 'john2.doe@dom', 'john3.doe.extern@dom', 'john4.doe.extern@dom']
    

    Personally I find list comprehensions are best when they are short and readable, so I would stick with the first option.

  • answered 2018-11-08 08:16 petruz

    Option without listcomprehensions:

    maillist = ["john.doe@dom", "john2.doe",    "john3.doe.e","john4.doe.extern@dom"]
    
    for i in range(len(maillist)): 
        if "@" not in maillist[i]:
            if maillist[i][-2:]== ".e": 
                maillist[i] += ("xtern@dom") 
            else: 
                maillist[i] +=  "@dom"
    

  • answered 2018-11-08 08:17 sudonym

    if you want a one-liner, combine list comprehension with multiple if/else statements:

    first_list = ["john.doe@dom", "john2.doe", "john3.doe.e","john4.doe.extern@dom"]
    
    second_list = [email + 'xtern@dom' if email.endswith(".e") else \
                   email if email.endswith("@dom") else "{}@dom".format(email) \
                       for email in first_list]
    
    print second_list
    

    Gives:

    ['john.doe@dom', 'john2.doe@dom', 'john3.doe.extern@dom', 'john4.doe.extern@dom']
    

  • answered 2018-11-08 08:18 Alan B.

    @Green Cell was faster than me and his answer seems to be correct. Here is a list comprehension that does the same thing :

    mails = ["john.doe@dom", "john2.doe", "john3.doe.e","john4.doe.extern@dom"]
    
    print mails
    
    mails = [mail if mail.endswith("@dom") else mail.replace(".e", ".extern@dom") if mail.endswith(".e") else "{}@dom".format(mail) for mail in mails]
    
    print mails
    

    Which outputs :

    ['john.doe@dom', 'john2.doe', 'john3.doe.e', 'john4.doe.extern@dom']
    ['john.doe@dom', 'john2.doe@dom', 'john3.doe.extern@dom', 'john4.doe.extern@dom']
    

    Hope this helps.

  • answered 2018-11-08 09:03 Hamperfait

    I came with a different solution in the end: Declaring a help function.

    def mailfy(mail):
       if mail.endswith(".c"):
         return mail[:-2] + "@dom"
       ...
    
    mails = [mailfy(x) for x in mails]