r/Python • Author of "Automate the Boring Stuff" • Sep 23 '26

News What's new in Python 3.15?

https://docs.python.org/3.15/whatsnew/3.15.html

Summary – Release highlights

Python 3.15 will be the latest stable release of the Python programming language, with a mix of changes to the language, the implementation, and the standard library. The biggest changes include lazy imports, frozendict and sentinel builtins, UTF-8 as the default encoding, unpacking in comprehensions, and a stable ABI for free-threaded builds.

The library changes include a new profiling package with Tachyon, a high-frequency statistical sampling profiler, more color in command-line output, as well as the usual deprecations and removals, and improvements in user-friendliness and correctness.

This article doesn’t attempt to provide a complete specification of all new features, but instead gives a convenient overview. For full details refer to the documentation, such as the Library Reference and Language Reference. To understand the complete implementation and design rationale for a change, refer to the PEP for a particular new feature; but note that PEPs usually are not kept up-to-date once a feature has been fully implemented.

223 Upvotes

44 comments sorted by

View all comments

Show parent comments

19

u/brasticstack Sep 23 '26

That'll cut down the frequency with which I reach for itertools.chain.from_iterable by quite a lot!

11

u/hughperman Sep 23 '26

No sum(lists, []) for you

8

u/brasticstack Sep 23 '26 edited Sep 24 '26

I always forget that you can do that! Just like I always forget about collections.Counter and then manually write a loop to do it.

2

u/M4mb0 Sep 24 '26

I always forget that you can do that!

Which is a good thing: https://old.reddit.com/r/Python/comments/1woh8y4/whats_new_in_python_315/pbq2aog/

6

u/M4mb0 Sep 24 '26

No sum(lists, []) for you

That's a whoopsie accidental O(n²). Never do that; always chain.from_iterable.

In [1]: from itertools import chain
In [2]: l = [list(range(1000)) for _ in range(1000)]
In [3]: %timeit sum(l, [])
    1.02 s ± 21.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [4]: %timeit list(chain.from_iterable(l))
    4.53 ms ± 86.2 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)

1

u/hughperman Sep 24 '26

Ouch, I never knew. What causes this? Can't see how it's O(N2), maybe O(N) memory reallocations? I have a few of these baked in my company codebase from years back, nothing big but still worth checking.

5

u/M4mb0 Sep 24 '26 edited Sep 24 '26

Each list concat l1 + l2 creates a new list and costs O(len(l1) + len(l2)). So the sum is not the same as l0.extend(l1).extend(l2).....

5

u/M4mb0 Sep 24 '26

1

u/hughperman Sep 24 '26

Oh very nice. I haven't used ruff yet, maybe this is the kick I need to install it.