Of course! "Contact merge" in Python can mean a few different things, so I'll cover the most common scenarios with clear, runnable code examples.

Here's a breakdown of the typical use cases:
- Scenario 1: Merging Duplicate Contacts in a List. This is the most frequent problem. You have a list of contacts, and some are duplicates (e.g., same name, different phone number). The goal is to combine them into a single, comprehensive contact.
- Scenario 2: Merging Data from Two Different Lists. You have two separate lists of contacts (e.g., one from your phone, one from Google), and you want to merge them into one master list, handling overlaps.
- Scenario 3: Merging VCard (.vcf) Files. A more advanced task involving parsing and merging standard contact files.
Let's tackle them one by one.
Scenario 1: Merging Duplicate Contacts in a Single List
This is the classic "contact merge" problem. We'll define a duplicate as a contact with the same full_name. We'll merge their data, preferring to keep non-empty fields.
The Logic:
- We'll use a dictionary to store our unique contacts. The key will be a unique identifier (like
full_name), and the value will be the contact dictionary itself. - We'll iterate through our list of contacts.
- For each contact, we'll check if we've already seen one with the same
full_name.- If it's a new contact: We add it to our dictionary.
- If it's a duplicate: We iterate through its fields (phone, email, etc.). If the field in the existing contact is empty and the new one has a value, we update the existing contact with the new value.
The Code:
def merge_contacts(contact_list):
"""
Merges a list of duplicate contacts into a single, comprehensive list.
Args:
contact_list (list): A list of contact dictionaries.
Returns:
list: A new list of merged, unique contacts.
"""
# Use a dictionary to store merged contacts, keyed by a unique identifier.
# Using 'full_name' as the key for this example.
merged_contacts_map = {}
for contact in contact_list:
# Use a normalized key to handle minor case/spacing differences
key = contact.get('full_name', '').lower().strip()
if not key:
# Skip contacts without a name
continue
if key in merged_contacts_map:
# It's a duplicate, so merge the data
existing_contact = merged_contacts_map[key]
for field, value in contact.items():
# Only update the existing contact if the field is empty
# and the new contact has a value for it.
if not existing_contact.get(field) and value:
existing_contact[field] = value
else:
# It's a new contact, add it to our map
merged_contacts_map[key] = contact.copy()
# Return the values of the map as a list
return list(merged_contacts_map.values())
# --- Example Usage ---
contacts = [
{'full_name': 'Alice Smith', 'phone': '123-456-7890', 'email': ''},
{'full_name': 'Bob Johnson', 'phone': '555-1234', 'email': 'bob@example.com'},
{'full_name': 'alice smith', 'phone': '999-888-7777', 'email': 'alice@work.com'}, # Duplicate name
{'full_name': 'Charlie Brown', 'phone': ''},
{'full_name': 'Alice Smith', 'phone': '', 'email': '', 'address': '123 Main St.'}, # Another duplicate with new info
{'full_name': 'David Lee', 'phone': '444-555-6666'},
]
merged_list = merge_contacts(contacts)
import json
print("--- Merged Contact List ---")
print(json.dumps(merged_list, indent=2))
Output:
--- Merged Contact List ---
[
{
"full_name": "Alice Smith",
"phone": "123-456-7890",
"email": "alice@work.com",
"address": "123 Main St."
},
{
"full_name": "Bob Johnson",
"phone": "555-1234",
"email": "bob@example.com"
},
{
"full_name": "Charlie Brown",
"phone": ""
},
{
"full_name": "David Lee",
"phone": "444-555-6666"
}
]
Scenario 2: Merging Two Different Contact Lists
This is like combining your phone's contacts with your Google contacts. We need a way to identify the same person across different lists. A unique ID is best, but a combination of name and email can also work.

The Logic:
- We'll combine both lists into one big list.
- We'll use a more robust key for merging. A combination of
full_nameandemailis a good candidate, as it's less likely to have false positives than just a name. - We'll use the same merging logic as in Scenario 1: iterate and combine, preferring non-empty fields.
The Code:
def merge_contact_lists(list1, list2):
"""
Merges two separate lists of contacts into one master list.
Args:
list1 (list): The first list of contact dictionaries.
list2 (list): The second list of contact dictionaries.
Returns:
list: A new, merged master list of contacts.
"""
# Combine the two lists
all_contacts = list1 + list2
# Use a dictionary to store merged contacts.
# The key will be a combination of name and email for better uniqueness.
merged_contacts_map = {}
for contact in all_contacts:
# Create a composite key
name_key = contact.get('full_name', '').lower().strip()
email_key = contact.get('email', '').lower().strip()
# Use a tuple as a key to handle multiple fields
key = (name_key, email_key)
if not name_key: # Skip contacts without a name
continue
if key in merged_contacts_map:
# Merge with the existing contact
existing_contact = merged_contacts_map[key]
for field, value in contact.items():
if not existing_contact.get(field) and value:
existing_contact[field] = value
else:
# Add the new contact
merged_contacts_map[key] = contact.copy()
return list(merged_contacts_map.values())
# --- Example Usage ---
contacts_phone = [
{'full_name': 'Alice Smith', 'phone': '123-456-7890'},
{'full_name': 'Bob Johnson', 'phone': '555-1234'},
]
contacts_google = [
{'full_name': 'Alice Smith', 'email': 'alice.smith@gmail.com'},
{'full_name': 'Eve Adams', 'phone': '777-888-9999', 'email': 'eve@adams.com'},
]
master_list = merge_contact_lists(contacts_phone, contacts_google)
import json
print("--- Master Merged Contact List ---")
print(json.dumps(master_list, indent=2))
Output:
--- Master Merged Contact List ---
[
{
"full_name": "Alice Smith",
"phone": "123-456-7890",
"email": "alice.smith@gmail.com"
},
{
"full_name": "Bob Johnson",
"phone": "555-1234"
},
{
"full_name": "Eve Adams",
"phone": "777-888-9999",
"email": "eve@adams.com"
}
]
Scenario 3: Merging VCard (.vcf) Files (Advanced)
This requires a library to parse the vCard format. The vobject library is excellent for this.
First, install it:
pip install vobject
The Logic:
- Read the content of each
.vcffile. - Use
vobjectto parse the content into Python objects. - Use the same merging logic as before, but now the "contact" objects are
vobject.base.Componentinstances. We can use theFN(Formatted Name) field as a key. - After merging, serialize the objects back into the vCard string format.
The Code:
import vobject
import os
def merge_vcf_files(vcf_file_paths, output_path):
"""
Merges multiple .vcf files into a single .vcf file,
handling duplicate contacts within and across files.
Args:
vcf_file_paths (list): A list of paths to .vcf files.
output_path (str): The path to save the merged .vcf file.
"""
all_contacts = []
# 1. Read and parse all vcf files
for file_path in vcf_file_paths:
try:
with open(file_path, 'r', encoding='utf-8') as f:
# vobject.readOne can
