Skip to main content

provides a simple and efficient way to remove duplicates from an iterable (even with unhashable elements, optional order preservation)

pip install screwduplicates

Tested against Windows 10 / Python 3.10 / Anaconda

Duplicate Removal:

It effectively removes duplicate elements from an iterable, ensuring that the returned iterable only contains unique values. This can be useful in scenarios where duplicate values need to be eliminated to avoid redundant or incorrect data.

Flexibility:

The function accepts a wide range of iterable types, including lists, tuples, and custom iterable objects. It can handle both hashable and unhashable elements, accommodating diverse data types.

Order Preservation:

The function provides an option to preserve the original order of elements in the iterable by setting the keep_order parameter to True. This is valuable when the order of elements matters, such as maintaining the sequence of items in a list.

Error Handling:

If the input iterable contains unhashable elements, the function gracefully handles the TypeError that arises during the conversion to a set. Instead of raising an error, it automatically switches to preserving order and includes a representation of the unhashable element in the output.

testdict = {
    "List": [5, 4, 1, 2, 2, 3, 4, 5],
    "Set": {1, 2, 3, 4, 5},
    "Tuple": (1, 3, 4, 2, 3, 4, 5, 5, 5, 2, 2, 1),
    "Dictionary": {"a": 1, "b": 2, "c": 3},
    "String": "Hello",
    "Bytes": b"Hello",
    "Bytearray": bytearray(b"Hello"),
    "List of strings": ["Hello", "World", "Hello"],
    "List of numbers": [2.5, 3.5, 1.5, 2.5, 3.5],
    "Empty list": [],
    "Set of strings": {"apple", "banana", "cherry"},
    "Set of numbers": {1, 2, 3, 4, 5},
    "Tuple of strings": ("apple", "banana", "cherry", "banana", "banana"),
    "Tuple of numbers": (3, 4, 5, 1, 2, 3, 4, 2, 3, 4, 2, 3, 4, 5),
    "Dictionary with numbers": {1: "one", 2: "two", 3: "three"},
    "Dictionary with strings": {"a": "apple", "b": "banana", "c": "cherry"},
    "List of mixed types": [1, "a", 2.5, True, True, True, 1, "a", "Hello"],
    "Set of mixed types": {1, "a", 2.5, True, "Hello"},
    "Tuple of mixed types": (1, "a", 2.5, True, "Hello", 1, "a", 2.5),
    "Nested list": [[1, 2], [3, 4], [5, 6], [1, 2], [3, 4], [3, 4], [5, 6]],
    "Nested set": {frozenset({1, 2}), frozenset({3, 4}), frozenset({5, 6})},
    "Nested tuple": ((1, 2), (3, 4), (5, 6), (3, 4)),
    "List with None value": [1, None, 3, None, 5],
    "Set with None value": {1, None, 3, None, 5},
    "Tuple with None value": (1, None, 3, None, 5),
    "List with boolean values": [True, False, True],
    "Set with boolean values": {True, False},
    "Tuple with boolean values": (True, False, True),
    "List with repeated values": [1, 1, 1, 1, 1],
    "Set with repeated values": {1, 1, 1, 1, 1},
    "Tuple with repeated values": (1, 1, 1, 1, 1),
    "List with mixed types and duplicates": [1, "a", 2, "a", 3, True, 3],
    "Set with mixed types and duplicates": {1, "a", 2, "a", 3, True},
    "Tuple with mixed types and duplicates": (1, "a", 2, "a", 3, True),
    "List with empty strings": ["", "World", "World", "Hello", "World"],
    "Set with empty strings": {"", "World", "Hello", "World", "World"},
}
from screwduplicates import del_duplicates
for key, item in testdict.items():
    print(f"\n---------------\n{key}:")
    print(f"Original: {item}")
    print(f"dont't keep order: {del_duplicates(item, keep_order=False)}")
    print(f"Keep order: {del_duplicates(item, keep_order=True)}")

---------------
List:
Original: [5, 4, 1, 2, 2, 3, 4, 5]
dont't keep order: [1, 2, 3, 4, 5]
Keep order: [5, 4, 1, 2, 3]
---------------
Set:
Original: {1, 2, 3, 4, 5}
dont't keep order: {1, 2, 3, 4, 5}
Keep order: {1, 2, 3, 4, 5}
---------------
Tuple:
Original: (1, 3, 4, 2, 3, 4, 5, 5, 5, 2, 2, 1)
dont't keep order: (1, 2, 3, 4, 5)
Keep order: (1, 3, 4, 2, 5)
---------------
Dictionary:
Original: {'a': 1, 'b': 2, 'c': 3}
dont't keep order: {'a': 1, 'b': 2, 'c': 3}
Keep order: {'a': 1, 'b': 2, 'c': 3}
---------------
String:
Original: Hello
dont't keep order: loeH
Keep order: Helo
---------------
Bytes:
Original: b'Hello'
dont't keep order: b'Hleo'
Keep order: b'Helo'
---------------
Bytearray:
Original: bytearray(b'Hello')
dont't keep order: bytearray(b'Hleo')
Keep order: bytearray(b'Helo')
---------------
List of strings:
Original: ['Hello', 'World', 'Hello']
dont't keep order: ['World', 'Hello']
Keep order: ['Hello', 'World']
---------------
List of numbers:
Original: [2.5, 3.5, 1.5, 2.5, 3.5]
dont't keep order: [1.5, 2.5, 3.5]
Keep order: [2.5, 3.5, 1.5]
---------------
Empty list:
Original: []
dont't keep order: []
Keep order: []
---------------
Set of strings:
Original: {'cherry', 'banana', 'apple'}
dont't keep order: {'cherry', 'banana', 'apple'}
Keep order: {'cherry', 'banana', 'apple'}
---------------
Set of numbers:
Original: {1, 2, 3, 4, 5}
dont't keep order: {1, 2, 3, 4, 5}
Keep order: {1, 2, 3, 4, 5}
---------------
Tuple of strings:
Original: ('apple', 'banana', 'cherry', 'banana', 'banana')
dont't keep order: ('cherry', 'banana', 'apple')
Keep order: ('apple', 'banana', 'cherry')
---------------
Tuple of numbers:
Original: (3, 4, 5, 1, 2, 3, 4, 2, 3, 4, 2, 3, 4, 5)
dont't keep order: (1, 2, 3, 4, 5)
Keep order: (3, 4, 5, 1, 2)
---------------
Dictionary with numbers:
Original: {1: 'one', 2: 'two', 3: 'three'}
dont't keep order: {1: 'one', 2: 'two', 3: 'three'}
Keep order: {1: 'one', 2: 'two', 3: 'three'}
---------------
Dictionary with strings:
Original: {'a': 'apple', 'b': 'banana', 'c': 'cherry'}
dont't keep order: {'a': 'apple', 'b': 'banana', 'c': 'cherry'}
Keep order: {'a': 'apple', 'b': 'banana', 'c': 'cherry'}
---------------
List of mixed types:
Original: [1, 'a', 2.5, True, True, True, 1, 'a', 'Hello']
dont't keep order: [1, 2.5, 'a', 'Hello']
Keep order: [1, 'a', 2.5, 'Hello']
---------------
Set of mixed types:
Original: {1, 2.5, 'a', 'Hello'}
dont't keep order: {1, 2.5, 'a', 'Hello'}
Keep order: {1, 2.5, 'a', 'Hello'}
---------------
Tuple of mixed types:
Original: (1, 'a', 2.5, True, 'Hello', 1, 'a', 2.5)
dont't keep order: (1, 2.5, 'a', 'Hello')
Keep order: (1, 'a', 2.5, 'Hello')
---------------
Nested list:
Original: [[1, 2], [3, 4], [5, 6], [1, 2], [3, 4], [3, 4], [5, 6]]
dont't keep order: [[1, 2], [3, 4], [5, 6]]
Keep order: [[1, 2], [3, 4], [5, 6]]
---------------
Nested set:
Original: {frozenset({3, 4}), frozenset({5, 6}), frozenset({1, 2})}
dont't keep order: {frozenset({3, 4}), frozenset({5, 6}), frozenset({1, 2})}
Keep order: {frozenset({3, 4}), frozenset({5, 6}), frozenset({1, 2})}
---------------
Nested tuple:
Original: ((1, 2), (3, 4), (5, 6), (3, 4))
dont't keep order: ((1, 2), (3, 4), (5, 6))
Keep order: ((1, 2), (3, 4), (5, 6))
---------------
List with None value:
Original: [1, None, 3, None, 5]
dont't keep order: [1, 3, None, 5]
Keep order: [1, None, 3, 5]
---------------
Set with None value:
Original: {1, 3, None, 5}
dont't keep order: {1, 3, None, 5}
Keep order: {1, 3, None, 5}
---------------
Tuple with None value:
Original: (1, None, 3, None, 5)
dont't keep order: (1, 3, None, 5)
Keep order: (1, None, 3, 5)
---------------
List with boolean values:
Original: [True, False, True]
dont't keep order: [False, True]
Keep order: [True, False]
---------------
Set with boolean values:
Original: {False, True}
dont't keep order: {False, True}
Keep order: {False, True}
---------------
Tuple with boolean values:
Original: (True, False, True)
dont't keep order: (False, True)
Keep order: (True, False)
---------------
List with repeated values:
Original: [1, 1, 1, 1, 1]
dont't keep order: [1]
Keep order: [1]
---------------
Set with repeated values:
Original: {1}
dont't keep order: {1}
Keep order: {1}
---------------
Tuple with repeated values:
Original: (1, 1, 1, 1, 1)
dont't keep order: (1,)
Keep order: (1,)
---------------
List with mixed types and duplicates:
Original: [1, 'a', 2, 'a', 3, True, 3]
dont't keep order: [3, 1, 2, 'a']
Keep order: [True, 'a', 2, 3]
---------------
Set with mixed types and duplicates:
Original: {'a', 1, 2, 3}
dont't keep order: {'a', 1, 2, 3}
Keep order: {'a', 1, 2, 3}
---------------
Tuple with mixed types and duplicates:
Original: (1, 'a', 2, 'a', 3, True)
dont't keep order: (3, 1, 2, 'a')
Keep order: (True, 'a', 2, 3)
---------------
List with empty strings:
Original: ['', 'World', 'World', 'Hello', 'World']
dont't keep order: ['', 'World', 'Hello']
Keep order: ['', 'World', 'Hello']
---------------
Set with empty strings:
Original: {'', 'World', 'Hello'}
dont't keep order: {'', 'World', 'Hello'}
Keep order: {'', 'World', 'Hello'}

Metadata

Release files for screwduplicates 0.11

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for screwduplicates 0.11
File Size Uploaded Provenance Actions
screwduplicates-0.11.tar.gz 6.4 kB Without provenance Details for screwduplicates-0.11.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for screwduplicates 0.11
File Interpreter ABI Platform Actions
screwduplicates-0.11-py3-none-any.whl Python 3 none any Details for screwduplicates-0.11-py3-none-any.whl

Total release size: 14.6 kB

Release files / screwduplicates-0.11.tar.gz

Download URL screwduplicates-0.11.tar.gz
Size 6.4 kB
Tags Source
SHA-256 checksum
How to use checksums
44174c46090533bf949d2ebc29730b6022734f5ae035b3b9493819155e3a7e42
BLAKE2b-256 checksum
How to use checksums
9b8294d03047577d051639bb2dabf02f79e020080e55ad5284e47bf94f1b7ad4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.10.10

Release files / screwduplicates-0.11-py3-none-any.whl

Download URL screwduplicates-0.11-py3-none-any.whl
Size 8.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a828f3db355cd342545d45cb3e6b4c312de4a0e786577546c17b45df8ff24754
BLAKE2b-256 checksum
How to use checksums
5798f7cc590145b2ef94e4e8cc98318710d729b1b6f4b733eb1530fc115d2f85
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.10.10

Security for screwduplicates 0.11

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.11 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page