A tool to diff dict, list, and set data structures
Project description
deep-diff
A Python tool to perform deep comparisons of complex data structures (dictionaries, lists, sets) and identify differences. Inspired by the npm package deep-diff.
Features
- 🔍 Deep Comparison: Compare nested dictionaries, lists, and sets
- 📊 Detailed Diff Output: Get structured difference records with paths to changed elements
- 🎯 Exception Paths: Exclude specific paths from comparison
- 🏷️ Type-Safe: Full type hints for better IDE support
- ✨ Modern Python: Requires Python 3.8+
Installation
pip install deep-diff
For development:
pip install -e ".[dev]"
Quick Start
Basic Dictionary Comparison
from deep_diff import diff
result = diff(
{'a': 1, 'c': 1},
{'b': 1, 'c': 1}
)
print(result)
# Output:
# [{'kind': 'D', 'path': ['a'], 'lhs': 1},
# {'kind': 'N', 'path': ['b'], 'rhs': 1}]
Excluding Paths
from deep_diff import diff
result = diff(
{'a': 1, 'c': 1},
{'b': 1, 'c': 1},
exceptions=[['a'], ['b']]
)
print(result) # None - all differences are excluded
Difference Record Format
Each difference record contains:
| Field | Type | Description |
|---|---|---|
kind |
str | Type of change: 'N' (new), 'D' (deleted), 'E' (edited), 'A' (array change) |
path |
list | Path to the changed property (e.g., ['user', 'name']) |
lhs |
any | Left-hand side value (undefined if kind == 'N') |
rhs |
any | Right-hand side value (undefined if kind == 'D') |
index |
int | Array index (only when kind == 'A') |
item |
dict | Nested change record (only when kind == 'A') |
Change Types
'N'- New property/element added'D'- Property/element deleted'E'- Property/element edited/modified'A'- Change within an array element at specific index
Examples
Dictionary Changes
from deep_diff import diff
# Modified value
diff({'a': 1}, {'a': 2})
# [{'kind': 'E', 'path': ['a'], 'lhs': 1, 'rhs': 2}]
# Nested structure
diff(
{'user': {'name': 'Alice', 'age': 30}},
{'user': {'name': 'Alice', 'age': 31}}
)
# [{'kind': 'E', 'path': ['user', 'age'], 'lhs': 30, 'rhs': 31}]
List Changes
from deep_diff import diff
# Modified element
diff([1, 2, 3], [1, 5, 3])
# [{'kind': 'E', 'path': [1], 'lhs': 2, 'rhs': 5}]
# Added element
diff([1, 2], [1, 2, 3])
# [{'kind': 'A', 'path': [], 'index': 2, 'item': {'kind': 'N', 'rhs': 3}}]
Set Changes
from deep_diff import diff
# Added elements
diff({1, 2}, {1, 2, 3})
# [{'kind': 'N', 'path': [], 'rhs': {3}}]
# Removed elements
diff({1, 2, 3}, {2, 3})
# [{'kind': 'D', 'path': [], 'lhs': {1}}]
Complex Structures
from deep_diff import diff
result = diff(
{
'name': 'my object',
'details': {'with': ['elements']}
},
{
'name': 'updated object',
'details': {'with': ['more', 'elements']}
}
)
# Returns detailed differences for each level
API Reference
diff(item1, item2, exceptions=None)
Compare two items and return their differences.
Parameters:
item1(any): The first item to compareitem2(any): The second item to compareexceptions(list, optional): List of paths to exclude from comparison. Each path is a list of keys/indices.
Returns:
Noneif items are equal- List of difference records if differences exist
Example:
from deep_diff import diff
# Equal items
diff([1, 2, 3], [1, 2, 3]) # Returns None
# Different items
diff([1, 2, 3], [1, 2, 4])
# [{'kind': 'E', 'path': [2], 'lhs': 3, 'rhs': 4}]
# With exceptions
diff(
{'a': 1, 'b': 2},
{'a': 10, 'b': 20},
exceptions=[['a']]
)
# [{'kind': 'E', 'path': ['b'], 'lhs': 2, 'rhs': 20}]
Development
Setup
# Clone the repository
git clone https://github.com/ider-zh/diff.git
cd diff
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install with development dependencies
pip install -e ".[dev]"
Running Tests
# Run all tests
pytest
# Run with coverage report
pytest --cov=deep_diff
# Run specific test file
pytest tests/test_deep_diff.py::TestDictDifferences
Code Quality
# Format code with black
black deep_diff tests
# Lint with ruff
ruff check deep_diff tests
# Type checking with mypy
mypy deep_diff
License
BSD 3-Clause License - see LICENSE file for details
Author
ider - GitHub
Email: 326737833@qq.com
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Changelog
Version 0.1.0 (Current)
- Complete modernization of the codebase
- Added full type hints
- Migrated to pyproject.toml
- Moved to pytest for testing
- Added comprehensive test suite
- Improved documentation
- Added GitHub Actions CI/CD
- Better code quality with ruff and black
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file deep_diff-0.1.0.tar.gz.
File metadata
- Download URL: deep_diff-0.1.0.tar.gz
- Upload date:
- Size: 8.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4ffac2c1932371a70b18b24bd710ca94237c8bf3bc06e28f58957c57ce841fe
|
|
| MD5 |
2ef4da5a49334917d4415f963281af56
|
|
| BLAKE2b-256 |
fb7040c3d2864a424f2d10383d0628c38c55a11c32c42a52412d9a28278aa579
|
File details
Details for the file deep_diff-0.1.0-py3-none-any.whl.
File metadata
- Download URL: deep_diff-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed11b210c42242a364a3ce0eed6dc6a8f42ae43ee371961f749b764585ebf57c
|
|
| MD5 |
eaf774acd0b8b7daa302b68f3628ab80
|
|
| BLAKE2b-256 |
9275e119971d697e6c523225177add870eb988fdd07a4a757a6b4886b9835b2f
|