Search code examples
pythoncsv

Python CSV module to write to a specific column without overwriting


So I need to use the csv module as I won't be able to add libraries to the device this needs to run from. Say I input the following csv.

input.csv

I need the script to

1.) Read the uid column and check each entry in the column to see if its blank or has a '@' symbol in it. if its blank it will skip, if it doesn't contain a '@' symbol it will add '@this.domain.com' to the end (# of columns aren't set and there might be more its not limited to just these 3)

3.) once that @this.domain.com is added it adds them to the 'mail' column, but the script should not overwrite any date in the uid or mail column.

Example of what the output should look like (doesn't matter if the empty entries are there or not) output.csv

I have the following code but it overwrites everything in the 'mail' column. I can't get it to just append to that column

import csv

def process_csv(input_filename, output_filename):
    with open(input_filename, 'r') as infile, open(output_filename, 'w', newline='') as outfile:
        reader = csv.DictReader(infile)
        fieldnames = reader.fieldnames + ['mail']
        
        writer = csv.DictWriter(outfile, fieldnames=fieldnames)
        writer.writeheader()

        for row in reader:
            offset_value = '@this.login.com'
            new_row = dict(row)

            for key, value in row.items():
                if key == 'uid' and value and '@' not in value:
                    new_row['mail'] = value + offset_value

            if 'mail' not in new_row or not new_row['mail']:
                new_row['mail'] = row.get('mail', '')

            writer.writerow(new_row)

process_csv('input.csv', 'output.csv')

Solution

  • You can simplify the logic by using a single statement to check if the uid is empty or lacks an @. If true, add the prefix (pre-defined) and gather it in a list of dicts for later use with writerows at the end of the process.

    import csv
    
    def process_csv(
        input_filename,
        output_filename,
        suffix="@this.domain.com"
    ):
        with (
            open(input_filename, "r") as inpf,
            open(output_filename, "w", newline="") as outf
        ):
            reader = csv.DictReader(inpf)
            writer = csv.DictWriter(outf, fieldnames=reader.fieldnames)
            writer.writeheader()
    
            emails = []
            for row in reader:
                writer.writerow(row)
                if row["uid"] and "@" not in row["uid"]:
                    emails.append({"mail": row["uid"] + suffix})
    
            writer.writerows(emails)
            
    process_csv("input.csv", "output.csv")
    

    Output :

    mail,uid,recid
    [email protected],uid1,23423423
    [email protected],uid2,4 45345
    [email protected],[email protected],6543645
    [email protected],uid4,5564
    ,uid10,
    [email protected],uid5,45645645
    [email protected],,
    [email protected],,
    [email protected],,
    [email protected],,
    [email protected],,
    [email protected],,
    

    Used input :

    mail,uid,recid
    [email protected],uid1,23423423
    [email protected],uid2,4 45345
    [email protected],[email protected],6543645
    [email protected],uid4,5564
    ,uid10,
    [email protected],uid5,45645645
    [email protected],,