Python email list splitter for emails

I’ve used ChatGPT to create a python script which will take a list of email addresses and put them in to X number of groups in CSV format.

The input format needs to be a single email address on each line. If you copy and paste a column of email addresses from Excel, it will match this format.

Example input:

alice@example.com
bob.smith@domain.org
carla.jones@sample.net
david_brown42@test.io
emily.zhao@website.com

Example output (in this case, 1 group only):

alice@example.com, bob.smith@domain.org, carla.jones@sample.net, david_brown42@test.io, emily.zhao@website.com


When you press the ‘Transform to CSV groups’ button, the list will be split in to X groups where each group is a single line of email addresses separated by a comma. You can choose the number of groups.

This is the format that email clients expect when sending an email to multiple recipients.

Here is the python3 code:

import tkinter as tk
from tkinter import scrolledtext


def split_emails(emails, num_groups=4):
    """
    Split a list of emails into num_groups roughly equal parts.
    Returns a list of lists.
    """
    n = len(emails)
    if n == 0:
        return [[] for _ in range(num_groups)]
    q, r = divmod(n, num_groups)
    groups = []
    index = 0
    for i in range(num_groups):
        size = q + (1 if i < r else 0)
        groups.append(emails[index:index+size])
        index += size
    return groups


def transform_action():
    # Get raw input and list of emails
    raw = input_text.get("1.0", tk.END)
    emails = [line.strip() for line in raw.splitlines() if line.strip()]

    # Get number of groups from input
    try:
        num_groups = int(group_entry.get())
        if num_groups < 1:
            num_groups = 1
    except ValueError:
        num_groups = 4

    # Update total count label
    count_label.config(text=f"Total emails: {len(emails)}")

    # Split into groups
    groups = split_emails(emails, num_groups=num_groups)

    # Prepare output
    output_text.configure(state=tk.NORMAL)
    output_text.delete("1.0", tk.END)
    for i, group in enumerate(groups, start=1):
        # Group label with count
        output_text.insert(tk.END, f"Group {i} ({len(group)} emails):\n\n")
        # CSV line
        csv_line = ', '.join(group)
        output_text.insert(tk.END, f"{csv_line}\n")
        # Spacing between groups
        output_text.insert(tk.END, "\n\n\n")
    output_text.configure(state=tk.DISABLED)


def clear_action():
    # Clear input and output areas and reset count
    input_text.delete("1.0", tk.END)
    output_text.configure(state=tk.NORMAL)
    output_text.delete("1.0", tk.END)
    output_text.configure(state=tk.DISABLED)
    count_label.config(text="Total emails: 0")
    group_entry.delete(0, tk.END)
    group_entry.insert(0, "4")

# Setup GUI
root = tk.Tk()
root.title("Email List Splitter")
root.geometry("800x550")  # increased height for controls

# Input label and text area
tk.Label(root, text="Enter one email per line:").pack(anchor=tk.W, padx=10, pady=(10, 0))
input_text = scrolledtext.ScrolledText(root, wrap=tk.WORD, height=10)
input_text.pack(fill=tk.BOTH, expand=False, padx=10, pady=5)

# Toolbar with buttons and count label
toolbar = tk.Frame(root)
toolbar.pack(fill=tk.X, padx=10, pady=5)

transform_btn = tk.Button(toolbar, text="Transform to CSV Groups", command=transform_action)
transform_btn.pack(side=tk.LEFT)

count_label = tk.Label(toolbar, text="Total emails: 0")
count_label.pack(side=tk.LEFT, padx=(10, 10))

# Group label and input field aligned left-to-right on right side
group_frame = tk.Frame(toolbar)
group_frame.pack(side=tk.RIGHT, padx=(0, 10))

group_label = tk.Label(group_frame, text="Number of groups")
group_label.pack(side=tk.LEFT, padx=(0, 5))

group_entry = tk.Entry(group_frame, width=5)
group_entry.insert(0, "4")
group_entry.pack(side=tk.LEFT)

clear_btn = tk.Button(toolbar, text="Clear email list", command=clear_action)
clear_btn.pack(side=tk.RIGHT, padx=(10, 10))

# Output label and text area
tk.Label(root, text="CSV Output for each group:").pack(anchor=tk.W, padx=10, pady=(10, 0))
output_text = scrolledtext.ScrolledText(root, wrap=tk.WORD, height=10, state=tk.DISABLED)
output_text.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)

# Start the GUI
root.mainloop()

Alternatively, you can download a Windows executable here: