NeuroAgent

How to Concatenate Two Lists in Python: Complete Guide

Learn multiple methods to concatenate lists in Python including + operator, extend(), unpacking, itertools.chain(), and list comprehensions. Compare performance and choose the best approach for your needs.

Question

How do I concatenate two lists in Python?

Example:

python
listone = [1, 2, 3]
listtwo = [4, 5, 6]

Expected outcome:

python
>>> joinedlist
[1, 2, 3, 4, 5, 6]
NeuroAgent

In Python, you can concatenate two lists using several methods including the + operator, the extend() method, or the * operator with unpacking. The most straightforward approach is using the + operator, which creates a new list containing all elements from both original lists. For in-place concatenation, you can use the extend() method, and for more advanced scenarios, you might consider list comprehensions or the itertools.chain() function.

Contents

Using the + Operator

The simplest and most readable way to concatenate two lists in Python is using the + operator. This method creates a new list containing all elements from both lists in order.

python
listone = [1, 2, 3]
listtwo = [4, 5, 6]

# Using the + operator
joinedlist = listone + listtwo
print(joinedlist)  # Output: [1, 2, 3, 4, 5, 6]

This approach is straightforward and creates a new list without modifying the original lists. It’s the most commonly used method for list concatenation in Python due to its clarity and simplicity.

Advantages:

  • Easy to read and understand
  • Doesn’t modify original lists
  • Works with multiple lists: list1 + list2 + list3

Disadvantages:

  • Creates a new list in memory
  • Can be inefficient for very large lists

Using the extend() Method

The extend() method modifies a list by adding all elements from another list to the end of the original list. This is useful when you want to concatenate lists in-place.

python
listone = [1, 2, 3]
listtwo = [4, 5, 6]

# Using extend() method
listone.extend(listtwo)
print(listone)  # Output: [1, 2, 3, 4, 5, 6]

If you want to keep the original lists unchanged, you first create a copy and then extend it:

python
listone = [1, 2, 3]
listtwo = [4, 5, 6]

# Create a copy and extend
joinedlist = list1.copy()
joinedlist.extend(list2)
print(joinedlist)  # Output: [1, 2, 3, 4, 5, 6]

Advantages:

  • Efficient for in-place concatenation
  • Memory efficient when modifying existing lists
  • Can be chained with other list operations

Disadvantages:

  • Modifies the original list (unless you create a copy first)
  • Less readable for simple concatenation

Using the * Operator with Unpacking

Python’s unpacking operator * can be used to concatenate multiple lists in a single expression:

python
listone = [1, 2, 3]
listtwo = [4, 5, 6]

# Using * operator with unpacking
joinedlist = [*listone, *listtwo]
print(joinedlist)  # Output: [1, 2, 3, 4, 5, 6]

This method is particularly useful when you have multiple lists to concatenate:

python
list1 = [1, 2]
list2 = [3, 4]
list3 = [5, 6]

# Concatenating multiple lists
result = [*list1, *list2, *list3]
print(result)  # Output: [1, 2, 3, 4, 5, 6]

You can also insert elements between lists:

python
list1 = [1, 2]
list2 = [3, 4]

# Inserting a separator
result = [*list1, 99, *list2]
print(result)  # Output: [1, 2, 99, 3, 4]

Advantages:

  • Clean and modern syntax
  • Flexible - allows inserting elements between lists
  • Works with multiple lists easily
  • Creates a new list without modifying originals

Disadvantages:

  • Slightly more verbose than simple + operator
  • Requires Python 3.5+ for this syntax

Using List Comprehensions

While not strictly concatenation, you can use list comprehensions to combine elements from multiple lists:

python
list1 = [1, 2, 3]
list2 = [4, 5, 6]

# Using list comprehension
joinedlist = [x for lst in [list1, list2] for x in lst]
print(joinedlist)  # Output: [1, 2, 3, 4, 5, 6]

This approach is more complex than other methods but can be useful in specific scenarios, especially when you need to filter or transform elements during concatenation.

python
# With filtering and transformation
list1 = [1, 2, 3]
list2 = [4, 5, 6, 7]

# Only include even numbers and multiply by 2
result = [x * 2 for lst in [list1, list2] for x in lst if x % 2 == 0]
print(result)  # Output: [4, 8, 12]

Advantages:

  • Allows filtering and transformation during concatenation
  • Flexible and powerful
  • Can handle complex logic

Disadvantages:

  • More complex syntax
  • Can be less readable for simple concatenation
  • Generally slower than direct concatenation methods

Using itertools.chain()

For very large lists, itertools.chain() can be more memory-efficient as it returns an iterator rather than creating a new list:

python
import itertools

list1 = [1, 2, 3]
list2 = [4, 5, 6]

# Using itertools.chain
joined_iterator = itertools.chain(list1, list2)
joinedlist = list(joined_iterator)
print(joinedlist)  # Output: [1, 2, 3, 4, 5, 6]

If you don’t need a list and can work with an iterator, this approach is even more memory-efficient:

python
import itertools

list1 = [1, 2, 3]
list2 = [4, 5, 6]

# Working with the iterator directly
for item in itertools.chain(list1, list2):
    print(item, end=' ')  # Output: 1 2 3 4 5 6

Advantages:

  • Memory efficient for large lists
  • Returns an iterator that can be processed lazily
  • Can chain multiple iterables

Disadvantages:

  • Requires importing itertools
  • Need to convert to list for most use cases
  • Slightly more complex syntax

Performance Comparison

Different concatenation methods have different performance characteristics. Here’s a comparison of the main approaches:

Method Time Complexity Space Complexity Modifies Original Best Use Case
list1 + list2 O(n+m) O(n+m) No Simple, readable concatenation
list1.extend(list2) O(m) O(1) Yes In-place concatenation
[*list1, *list2] O(n+m) O(n+m) No Modern syntax with flexibility
itertools.chain() O(1) for iterator O(1) for iterator No Memory-efficient processing
List comprehension O(n+m) O(n+m) No Complex transformations

For small to medium-sized lists, the performance differences are negligible. For very large lists, extend() is most memory-efficient for in-place operations, while itertools.chain() is best for memory-efficient iteration.

python
import timeit

# Performance test setup
list1 = list(range(1000))
list2 = list(range(1000, 2000))

# Testing different methods
plus_time = timeit.timeit('list1 + list2', setup='from __main__ import list1, list2', number=10000)
extend_time = timeit.timeit('list1.copy(); temp.extend(list2)', setup='from __main__ import list1, list2; temp = list1.copy()', number=10000)
unpack_time = timeit.timeit('[*list1, *list2]', setup='from __main__ import list1, list2', number=10000)

print(f"+ operator: {plus_time:.4f} seconds")
print(f"extend(): {extend_time:.4f} seconds") 
print(f"unpacking: {unpack_time:.4f} seconds")

Best Practices

When choosing a list concatenation method in Python, consider these guidelines:

When to Use Each Method

Use + operator when:

  • You want simple, readable code
  • You need to concatenate just two lists
  • You want to keep original lists unchanged
  • You’re working with small to medium-sized lists

Use extend() when:

  • You want to modify a list in-place
  • You’re concerned about memory efficiency
  • You’re building a list in a loop

Use unpacking (*) when:

  • You want modern, flexible syntax
  • You need to concatenate multiple lists
  • You want to insert elements between lists
  • You’re using Python 3.5+

Use itertools.chain() when:

  • You’re working with very large lists
  • You need memory-efficient iteration
  • You’re processing lists sequentially without storing the result

Common Pitfalls to Avoid

  1. Modifying Original Lists: Remember that extend() modifies the list in-place. If you need to preserve the original, create a copy first.

  2. Inefficient Concatenation in Loops: Avoid repeated concatenation in loops using + operator, as it creates new lists each time. Use extend() or list comprehensions instead.

python
# Inefficient - creates many intermediate lists
result = []
for sublist in list_of_lists:
    result = result + sublist  # Bad!

# Efficient - extends the list in-place
result = []
for sublist in list_of_lists:
    result.extend(sublist)  # Good!
  1. Memory Issues with Large Lists: For very large lists, consider itertools.chain() or generator expressions to avoid memory problems.

Advanced Techniques

For more complex scenarios, you can combine these methods:

python
# Conditional concatenation with unpacking
list1 = [1, 2, 3]
list2 = [4, 5, 6]
list3 = [7, 8, 9]

# Only include list2 if condition is met
condition = True
result = [*list1, *list2] if condition else [*list1, *list3]

# Concatenate multiple lists with separator
lists = [[1, 2], [3, 4], [5, 6]]
separator = [0]
result = []
for i, lst in enumerate(lists):
    result.extend(lst)
    if i < len(lists) - 1:
        result.extend(separator)

Conclusion

Python offers several effective methods for concatenating lists, each with its own advantages and use cases:

  1. + operator is the most straightforward and readable method for simple concatenation
  2. extend() method is efficient for in-place concatenation and memory optimization
  3. Unpacking operator (*) provides modern, flexible syntax for multiple lists
  4. itertools.chain() offers memory-efficient iteration for large datasets
  5. List comprehensions allow complex transformations during concatenation

Choose the method that best fits your specific needs: readability, performance, memory efficiency, or flexibility. For most everyday programming, the + operator or extend() method will serve you well, while the unpacking syntax provides a modern alternative for more complex scenarios.


Sources

  1. Python Documentation - Sequence Types
  2. Real Python - Python List Methods
  3. Python.org - Built-in Types
  4. GeeksforGeeks - Python List Concatenation
  5. Stack Overflow - Best Ways to Concatenate Lists