#36215: Use PEP 448 unpacking to concatenate iterables
-------------------------------------+-------------------------------------
Reporter: Aarni Koskela | Owner: Aarni
Type: | Koskela
Cleanup/optimization | Status: assigned
Component: Documentation | Version: 5.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Natalia Bidart):
* component: Uncategorized => Documentation
* owner: (none) => Aarni Koskela
* stage: Unreviewed => Accepted
* status: new => assigned
* version: 5.1 => 5.2
Comment:
I performed some more "traditional" benchmarking (see the test script and
results below), and while there is a performance gain, I wouldn't
necessarily accept this ticket based solely on that. However, I do believe
we can accept the ticket and PR due to the existing precedent and
preference in #28909. Additionally, I agree that the code reads better and
is more robust (the tuple argument really stood out to me).
To proceed with the proposed changes, I think we need in the two separate
commits as follows:
* One commit making the code changes with commit message as used before:
`Refs #28909 -- Simplifed code using unpacking generalizations.`.
* A second commit that refs this ticket which updates the contributing
docs regarding python style.
Bonus point for providing a linter that would check for this in our code
when running lint checks!
Test script and results:
{{{#!python
import timeit
setup_code = """
d1 = {str(i): i for i in range(500)}
d2 = {str(i): -i for i in range(500, 1000)}
d3 = {str(i): i for i in range(1, 500, 3)}
merged = {}
"""
stmt_unpack = "merged = {**d1, **d2, **d3}"
stmt_update = "merged.update(d1); merged.update(d2); merged.update(d3)"
print("Dictionary unpacking **:", timeit.timeit(stmt_unpack,
setup=setup_code, number=100000))
print("Dictionary update:", timeit.timeit(stmt_update, setup=setup_code,
number=100000))
setup_code = """
list1 = list(range(0, 100))
list2 = list(range(0, 100, 3))
set1 = {str(i) for i in range(100, 200)}
gen1 = (i for i in range(200, 300))
merged = []
merged_set = set()
"""
# Using +
stmt_plus = "merged = list1 + list2 + list(set1) + list(gen1)"
# Using extend()
stmt_extend = "merged.extend(list1); merged.extend(list2);
merged.extend(set1); merged.extend(gen1)"
# Using update()
stmt_update = "merged_set.update(list1); merged_set.update(list2);
merged_set.update(set1); merged_set.update(gen1)"
# Using * unpacking
stmt_star = "merged = [*list1, *list2, *set1, *gen1]"
# Using * unpacking on set
stmt_star_set = "merged_set = {*list1, *list2, *set1, *gen1}"
print("Using + :", timeit.timeit(stmt_plus, setup=setup_code,
number=100000))
print("Using extend():", timeit.timeit(stmt_extend, setup=setup_code,
number=100000))
print("Using update():", timeit.timeit(stmt_update, setup=setup_code,
number=100000))
print("Using * unpacking:", timeit.timeit(stmt_star, setup=setup_code,
number=100000))
print("Using * unpacking for set:", timeit.timeit(stmt_star_set,
setup=setup_code, number=100000))
}}}
With results:
{{{
$ python unpacking.py
Dictionary unpacking **: 1.0474329520002357
Dictionary update: 1.2098236809979426
Using + : 0.12143729099989287
Using extend(): 0.1061674349984969
Using update(): 0.13288522899892996
Using * unpacking: 0.0665277590014739
Using * unpacking for set: 0.1808751239987032
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/36215#comment:3>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/django-updates/010701955d5e1dd3-243f0fa9-2455-496e-9713-13f3f6f591a0-000000%40eu-central-1.amazonses.com.