Back to Blog
Python

Python Set Union: Combining Sets with | and union()

python set union: Learn how to combine Python sets using the union() method and the | operator, including handling multiple sets and iterables, with practical examples.

PythonSetsSet OperationsData StructuresPython Syntax
Diagram of two sets merging into a union set with overlapping elements highlighted.

Python set union returns a new set containing all elements from the original sets, removing duplicates. The most common ways to perform a python set union are the | operator and the union() method. Both produce the same result but differ in how they handle iterables and in their method-call syntax.

Basic Syntax and Minimal Example

The | operator works directly between two sets. The union() method can be called on a set and accepts one or more arguments, which can be sets or any iterable.

s1 = {1, 2, 3} s2 = {3, 4, 5} # Using the | operator result1 = s1 | s2 print(result1) # {1, 2, 3, 4, 5} # Using the union() method result2 = s1.union(s2) print(result2) # {1, 2, 3, 4, 5}

Both approaches create a new set and leave s1 and s2 unchanged. This is the core behavior you'll encounter when working with set union.

union() vs | Operator: Key Differences

The most important distinction is that | requires both operands to be sets, while union() accepts any iterable as an argument. For example, you can pass a list or a tuple to union() without converting it to a set first.

s = {1, 2, 3} items = [3, 4, 5] # This works result = s.union(items) print(result) # {1, 2, 3, 4, 5} # This raises TypeError: unsupported operand type(s) for |: 'set' and 'list' # result = s | items

The | operator is more restrictive but also more readable when you are working exclusively with sets. The union() method is more flexible, especially when you need to combine a set with data stored in a list, tuple, or another iterable.

Combining Multiple Sets

The union() method can accept multiple arguments in a single call, which is convenient when merging more than two collections. The | operator requires chaining, which works but can become less readable with many operands.

s1 = {1, 2} s2 = {2, 3} s3 = {3, 4} # Multiple arguments with union() result = s1.union(s2, s3) print(result) # {1, 2, 3, 4} # Chaining the | operator result = s1 | s2 | s3 print(result) # {1, 2, 3, 4}

When you have a dynamic number of sets, you can use union() with unpacking:

sets = [{1, 2}, {2, 3}, {3, 4}] result = set().union(*sets) print(result) # {1, 2, 3, 4}

This pattern is useful when the number of sets is determined at runtime, for example when processing a list of groups.

In-Place Union with update()

If you want to modify the original set instead of creating a new one, use the update() method. It performs the same element addition as union but mutates the set in place and returns None.

s = {1, 2, 3} s.update([3, 4, 5]) print(s) # {1, 2, 3, 4, 5}

The |= operator provides a shorthand for in-place union when the right-hand side is a set:

s = {1, 2, 3} s |= {3, 4, 5} print(s) # {1, 2, 3, 4, 5}

Note that update() accepts any iterable, while |= requires a set, mirroring the difference between union() and |. Choose update() when you want to avoid allocating a new set and you don't need the original set afterwards.

Performance and Memory Behavior

The union() method and the | operator both create a new set, which means they allocate memory for the result. The time complexity is O(len(s1) + len(s2)) for two sets, because each element from both sets must be hashed and inserted into the new set. For multiple sets, the cost is proportional to the total number of elements across all inputs.

In contrast, update() modifies the existing set in place, avoiding the allocation of a new set object. This can reduce memory churn in loops where you repeatedly merge many small sets into one accumulator. However, the time complexity remains the same because each element still needs to be inserted.

There is no inherent performance advantage to using | over union() when both operands are sets; the difference is negligible. The main performance consideration is whether you need the original set preserved. If not, update() is more memory-efficient.

Common Mistakes and Edge Cases

One frequent error is using | with a non-set iterable. As shown earlier, this raises a TypeError. If you are not sure whether an object is a set, either convert it explicitly with set() or use union() which accepts any iterable.

Another subtle issue is that union() does not modify the original set. If you forget to assign the result, the union is lost:

s1 = {1, 2} s2 = {3, 4} s1.union(s2) # result is discarded print(s1) # still {1, 2}

This is a common source of bugs, especially for developers coming from languages where in-place modification is more common.

When working with empty sets, union behaves as expected: set().union() returns an empty set, and s | set() returns a copy of s. There are no special edge cases beyond that.

Finally, remember that sets require hashable elements. If you attempt to union sets containing lists or dictionaries, you'll get a TypeError because those types are unhashable. This is a constraint of sets themselves, not of the union operation.

For most real-world use cases, the | operator is the most readable choice when both operands are sets. Use union() when you need to accept arbitrary iterables or when you have multiple sets to combine in one call. Use update() when you want to merge into an existing set without creating a new object.

python set union: Practical Usage and Code Examples | RYUSLOG DEV