Blog Post #119: The Easiest Way to Merge Collections: * and ** Unpacking

In Post #118, we saw how the * operator could be used on the left side of an assignment to collect multiple items into a list (e.g., first, *rest = my_list). This unpacking concept has a powerful counterpart when used on the right side of an expression, inside list or dictionary literals.

In this post, we’ll learn the modern, Pythonic way to merge lists and dictionaries using the * (iterable unpacking) and ** (dictionary unpacking) operators, available in Python 3.5+.

Merging Lists with * Unpacking

A common task is to combine two or more lists into a single new list. While you can do this with the + operator (e.g., list1 + list2), the unpacking operator * offers more flexibility and readability.

The Unpacking Syntax

When used inside a new list literal, the * operator “unpacks” the elements from an existing list and places them individually into the new one.

first_list = [1, 2, 3]
second_list = [4, 5, 6]

# Unpack both lists into a new list
merged_list = [*first_list, *second_list]

print(merged_list)

The output will be a single, combined list: [1, 2, 3, 4, 5, 6]

The Flexibility Advantage

The real power of this syntax is how easily you can combine unpacked lists with other individual elements. This is much cleaner than multiple + operations.

first_list = [1, 2, 3]
second_list = [4, 5, 6]

full_list = ["start", *first_list, "middle", *second_list, "end"]

print(full_list)

The output is a seamlessly constructed list: ['start', 1, 2, 3, 'middle', 4, 5, 6, 'end']

Merging Dictionaries with ** Unpacking

The same principle applies to dictionaries, but it uses the double asterisk ** operator. This operator unpacks the key-value pairs from one dictionary into a new one.

The Basic Merge

We learned about the .update() method in Post #69. The ** unpacking syntax provides a more expressive, literal way to create a new, merged dictionary.

dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}

merged_dict = {**dict1, **dict2}
print(merged_dict)

The output is one combined dictionary: {'a': 1, 'b': 2, 'c': 3, 'd': 4}

Handling Duplicate Keys: Last One Wins

This is a critical rule to remember. If the dictionaries you are merging share any keys, the value from the last dictionary in the expression will be used.

dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 99, 'c': 4} # 'b' is a shared key

# The value for 'b' from dict2 will overwrite the one from dict1
merged_dict = {**dict1, **dict2}

print(merged_dict)

The output will be: {'a': 1, 'b': 99, 'c': 4}

Combining with Other Pairs

Just like with lists, this syntax makes it easy to add or override specific key-value pairs in a single expression.

base_config = {'font': 'Arial', 'size': 12}

# Create a new config, overriding 'size' and adding 'color'
custom_config = {**base_config, 'size': 14, 'color': 'blue'}

print(custom_config)

The output is: {'font': 'Arial', 'size': 14, 'color': 'blue'}

What’s Next?

The * and ** unpacking operators provide a modern, readable, and highly flexible way to construct new lists and dictionaries from existing ones. They are a perfect example of the expressive power of Pythonic code.

We’ve seen many ways to build and modify collections. Next, we’re going to learn one of the most celebrated features in Python: a concise, one-line syntax for creating new lists from existing ones, complete with filtering and transformation logic. In Post #120, we will be introduced to list comprehensions.

Author

Debjeet Bhowmik

Experienced Cloud & DevOps Engineer with hands-on experience in AWS, GCP, Terraform, Ansible, ELK, Docker, Git, GitLab, Python, PowerShell, Shell, and theoretical knowledge on Azure, Kubernetes & Jenkins. In my free time, I write blogs on ckdbtech.com

Leave a Comment