Combining Lists in Python for Data Science

Datatypes Mar 19, 2026

Combining Lists in Python for Data Science – Best Practices 2026

Combining multiple lists is a daily operation in data science — whether merging feature lists, concatenating predictions, joining column names, or building composite datasets. Python offers several clean and efficient ways to combine lists.

TL;DR — Best Methods to Combine Lists

  • + operator or list1 + list2 → Simple concatenation
  • list.extend() → In-place extension
  • zip() → Pair-wise combination
  • itertools.chain() → Memory-efficient for large lists

1. Basic List Combination Techniques

features1 = ["amount", "quantity", "profit"]
features2 = ["region", "category", "log_amount"]

# 1. Using + operator (creates new list)
all_features = features1 + features2

# 2. Using extend() - modifies in place
features1.extend(features2)

# 3. Using unpacking (very Pythonic)
combined = [*features1, *features2]

2. Real-World Data Science Examples

import pandas as pd

# Small inline sample so this example runs as-is.
# In a real project you would load it: df = pd.read_csv("sales_data.csv")
df = pd.DataFrame({
    "customer_id": [101, 102, 103, 104, 105, 106],
    "customer_name": ["Ana", "Ben", "Chen", "Dana", "Eli", "Fay"],
    "order_date": ["2026-01-05", "2026-01-12", "2026-02-03",
                   "2026-02-18", "2026-03-01", "2026-03-09"],
    "amount": [1250.75, 890.50, 2340.00, 1780.25, 2615.40, 450.00],
    "quantity": [3, 2, 5, 4, 6, 1],
    "profit": [312.69, 222.63, 585.00, 445.06, 653.85, 112.50],
    "region": ["North", "South", "East", "North", "West", "South"],
    "category": ["Electronics", "Books", "Electronics", "Home", "Home", "Books"],
    "rating": [5, 4, None, 3, 5, 4],
})

# Example 1: Combining numeric and categorical feature lists
numeric_features = [col for col in df.columns
                    if pd.api.types.is_numeric_dtype(df[col]) and col != "customer_id"]
# pandas 3 stores text as the "str" dtype, so test for strings instead of "object"
categorical_features = [col for col in df.columns
                        if pd.api.types.is_string_dtype(df[col])]

all_model_features = numeric_features + categorical_features

# Example 2: Pairing features with their importance scores using zip
importance_scores = [0.42, 0.31, 0.18, 0.09]
feature_importance_pairs = list(zip(all_model_features, importance_scores))

# Example 3: Building a full column list for export
base_cols = ["customer_id", "order_date"]
metric_cols = ["amount", "profit", "quantity"]
final_columns = base_cols + metric_cols + ["region", "category"]

3. Advanced Combination Patterns

from itertools import chain

# Memory-efficient way for very large lists
large_list1 = list(range(1_000_000))
large_list2 = list(range(1_000_000, 2_000_000))

def process(item):
    return item * 2

# chain() walks both lists without building a third, combined list
total = sum(process(item) for item in chain(large_list1, large_list2))
print(total)

# Combining with conditions
high_value_features = [f for f in all_model_features if "amount" in f or "profit" in f]
final_feature_set = numeric_features + high_value_features

4. Best Practices in 2026

  • Use + or unpacking [*list1, *list2] for small to medium lists
  • Use .extend() when you want to modify the original list
  • Use itertools.chain() for very large lists or memory-sensitive code
  • Prefer zip() when you need to combine lists element-wise
  • Avoid repeated + in loops (it creates many temporary lists)

Choosing the Right Method

The methods above look similar but behave differently. a + b and [*a, *b] build a new list and leave the originals untouched. a.extend(b) and a += b modify a in place, which matters when other code holds a reference to a. itertools.chain() creates nothing at all — it simply yields items from each input in turn, which is ideal when you only need to loop once.

MethodNew list?Best for
a + bYesTwo lists, readable code
[*a, *b, "x"]YesSeveral lists plus extra items
a.extend(b)No (in place)Growing one list in a loop
chain(a, b)No (lazy)One pass over large data

Worked Example: Merging Feature Lists Without Duplicates

base = ["amount", "quantity", "profit"]
engineered = ["log_amount", "profit", "is_weekend"]   # "profit" repeats

merged = base + engineered
print(merged)

# dict.fromkeys keeps the FIRST occurrence and preserves order
unique_ordered = list(dict.fromkeys(merged))
print(unique_ordered)
# ['amount', 'quantity', 'profit', 'log_amount', 'is_weekend']

A set would also remove the duplicate, but sets do not keep order. For column lists, where order often matters for exports and models, dict.fromkeys() is the cleaner choice.

Common Mistakes

  • Using append() instead of extend(): a.append(b) adds the whole list as one nested item
  • Writing a = a.extend(b): extend() returns None, so a is lost
  • Concatenating inside a loop (result = result + chunk): it copies the list every time; use extend()
  • Forgetting that chain() is single-use: once consumed, it yields nothing

Quick Summary

  • Use + or unpacking for new lists, extend() for in-place growth
  • Use itertools.chain() for one lazy pass over large inputs
  • Use dict.fromkeys() to merge while removing duplicates and keeping order

Conclusion

Combining lists is a core skill in data science. In 2026, use the + operator and unpacking for most cases, extend() for in-place modification, and itertools.chain() when working with very large lists. Mastering these techniques will help you write cleaner, faster, and more memory-efficient code when building feature sets, merging results, or preparing data for modeling.

Next steps:

  • Review how you currently combine lists in your projects and apply the most appropriate method for each situation

Related Tutorials

Share:
Last updated: March 2026
Built-in Functions in Python 2026 str() in Python 2026: String Conversion + Modern Formatting & Best Practices memoryview with JAX in Python 2026: Zero-Copy NumPy → JAX Array Interop + Efficient ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + GPU Pinning & ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + ML Examples memoryview with NumPy & PyTorch in Python 2026: Zero-Copy Views, Efficient Slicing & ML Interop Examples memoryview with NumPy in Python 2026: Zero-Copy Views, Efficient Slicing & Real ML Examples memoryview() in Python 2026: Zero-Copy Magic for Large Binary Data + Real Examples import() in Python 2026: How It Works, Security Risks & Modern Alternatives (importlib) zip() in Python 2026: How to Use It, strict=True Behavior & Real-World Examples vars() in Python 2026: Accessing Object Namespace + Modern Introspection Patterns type() in Python 2026: Dynamic Type Inspection & Object Creation + Modern Patterns tuple() in Python 2026: Immutable Sequences + Modern Patterns & Best Practices super() in Python 2026: Method Resolution & Modern Inheritance Patterns sum() in Python 2026: Summing Iterables + Modern Numeric Patterns & Best Practices staticmethod() in Python 2026: Static Methods, Utility Functions & Modern Best Practices sorted() in Python 2026: Sorting Iterables + Modern Patterns & Best Practices slice() in Python 2026: Creating Slice Objects + Modern Patterns & Best Practices setattr() in Python 2026: Dynamic Attribute Setting + Modern Patterns & Safety set() in Python 2026: Mutable Sets Creation + Modern Patterns & Best Practices