Install & Compatibility
Where this runs
tested against v1.4.4 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.920 runs
installs and imports cleanly · install 0.0s · import 0.244s · 94MB
glibcpy 3.10–3.920 runs
installs and imports cleanly · install 3.9s · import 0.256s · 91MB
93MB installed
● package 93MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
creator
✓ from deap import creator
Used to create custom types for fitness and individuals.
base
✓ from deap import base
Contains the Toolbox and base classes for fitness and individuals.
tools
✓ from deap import tools
Provides a collection of evolutionary operators (selection, crossover, mutation).
algorithms
✓ from deap import algorithms
Contains high-level evolutionary algorithms like `eaSimple`, `eaMuPlusLambda`.
This quickstart demonstrates the classic OneMax problem, where the goal is to evolve a binary string (list of 0s and 1s) to maximize the number of 1s. It showcases the core DEAP workflow: defining custom types (Fitness and Individual), initializing the Toolbox with genetic operators, and running a simple evolutionary algorithm.
import random
from deap import creator, base, tools, algorithms
# 1. Define problem: Maximize sum of bits in a binary string (OneMax problem)
# Create a FitnessMax class, higher values are better
creator.create("FitnessMax", base.Fitness, weights=(1.0,))
# Create an Individual class, which is a list and has a fitness attribute
creator.create("Individual", list, fitness=creator.FitnessMax)
# 2. Initialize Toolbox
toolbox = base.Toolbox()
# Register function to generate random boolean attributes (0 or 1)
toolbox.register("attr_bool", random.randint, 0, 1)
# Register function to create an individual: 100 random booleans
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_bool, 100)
# Register function to create a population: a list of individuals
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
# 3. Define Evaluation Function
def evalOneMax(individual):
return sum(individual), # The comma is crucial: returns a tuple
toolbox.register("evaluate", evalOneMax)
# 4. Define Genetic Operators
toolbox.register("mate", tools.cxTwoPoint) # Two-point crossover
toolbox.register("mutate", tools.mutFlipBit, indpb=0.05) # Flip bit mutation with 5% probability
toolbox.register("select", tools.selTournament, tournsize=3) # Tournament selection with size 3
# 5. Run the Evolutionary Algorithm
def main():
random.seed(42) # For reproducibility
population = toolbox.population(n=300)
# Number of generations, crossover probability, mutation probability
NGEN, CXPB, MUTPB = 40, 0.7, 0.2
# The main evolutionary loop
print(f"Start of evolution: Population size {len(population)}")
population, logbook = algorithms.eaSimple(population, toolbox, cxpb=CXPB, mutpb=MUTPB, ngen=NGEN, verbose=False)
# Get the best individual(s) from the final population
best_ind = tools.selBest(population, 1)[0]
print(f"Best individual: {best_ind}, Fitness: {best_ind.fitness.values[0]}")
if __name__ == "__main__":
main()
Debug
Known issues
gotchaThe evaluation function for an individual MUST return a tuple of fitness values, even for a single objective. For example, `return sum(individual),` (note the comma) or `return (sum(individual),)`.fixAlways return a tuple from your evaluation function.
affects: All versions
gotchaWhen defining `creator.create("Fitness...", base.Fitness, weights=...)`, the `weights` tuple determines if the objective is maximization (positive weight, e.g., `(1.0,)`) or minimization (negative weight, e.g., `(-1.0,)`). Ensure the sign matches your optimization goal.fixUse `weights=(1.0,)` for maximization and `weights=(-1.0,)` for minimization.
affects: All versions
breakingFor Genetic Programming (GP), the `gp.stringify()` function was replaced by `PrimitiveTree.__str__()`. Also, `gp.evaluate()` and `gp.lambdify()` were merged and replaced by a single `gp.compile()` function. The `tools.Checkpoint` class was removed in favor of simpler manual checkpointing.fixConsult the 'Release Highlights' and 'Porting Guide' in the DEAP documentation for the specific version you are upgrading from/to. For `gp.stringify()`, use `str(primitive_tree_object)`. For GP evaluation/lambdification, use `gp.compile()`.
affects: 1.1.x to 1.2.x, 1.3.x to 1.4.x (specific changes across versions)
deprecatedOlder versions of DEAP (pre-1.x, particularly around 0.8) for Python 3 installations might have required `setuptools<=58` due to the use of `2to3` for source translation. This is unlikely to affect modern installations (Python 3.6+ and DEAP 1.x+).fixFor current DEAP versions, this is generally not an issue. If encountering `setuptools` related errors during old Python 3 installs, try `pip install setuptools==57.5.0` as a workaround.
affects: <1.0
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'deap'
The 'deap' library is not installed in the active Python environment or the environment in which the code is being executed.
fixInstall the library using pip: `pip install deap`
NotImplementedError: pool objects cannot be passed between processes or pickled
When using Python's `multiprocessing` module with DEAP, certain objects (like `Pool` instances or functions/classes defined locally within a script) cannot be serialized (pickled) and passed between processes, especially on Windows or when not guarded by `if __name__ == '__main__':`.
fixEnsure that functions intended for multiprocessing are defined at the top-level of a module. For scripts using `multiprocessing.Pool`, wrap the main execution block in `if __name__ == '__main__':`.
TypeError: object of type 'int' has no len()
This error occurs when a DEAP operator or function, such as a selection or mutation operator, expects an iterable (e.g., a list or tuple) but receives an integer or another non-iterable type.
fixEnsure that your evaluation function always returns a tuple for the fitness values, even for single-objective optimization (e.g., `return value,` instead of `return value`). Also, verify that any custom individual types or operators handle data as iterables where required.
Evaluation function must return a tuple (conceptual error)
DEAP expects the fitness value(s) returned by the evaluation function to always be a tuple, even for single-objective optimization. Returning a single numerical value directly (e.g., `return my_score`) instead of a tuple (e.g., `return my_score,`) leads to TypeErrors or unexpected behavior in subsequent DEAP operations.
fixModify your evaluation function to always return a tuple, even if it contains only one element: `def evaluate_individual(individual): # ... calculate score ... return score,`
TypeError: 'NoneType' object is not subscriptable
In Genetic Programming (GP) with DEAP, this error often arises when `gp.compile` (which transforms a tree expression into a callable function) fails and returns `None`, and subsequent code attempts to call or subscript this `None` object. This can be caused by ill-formed trees, missing primitives/terminals in the `PrimitiveSet`'s context, or type mismatches in strongly typed GP.
fixReview the `PrimitiveSet` (`pset`) definition to ensure all necessary primitives and terminals are correctly registered and available in the `pset.context`. If using strongly typed GP, verify that the type constraints are consistently met throughout the tree generation and manipulation processes.
Upgrade
Version history
1.4.4latest on PyPI · released Apr 17, 2026
Audit
Dependencies
numpyoptionalRecommended for Evolution Strategies (e.g., CMA-ES) and creating individuals inheriting from NumPy arrays.
matplotliboptionalRecommended for visualization of results.