This is not the NaN you are looking for
Alternate title: "NaN - More than Not a Number"
- Python oddities concerning NaN
- Live demo a dict that allows use of NaN as a key the way it would be intuitively, so that all NaN values are treated as one.
- Live demo a Counter that counts how many occurences of NaN exist
Questions
- What about
copy.copy?
Description
Have you ever wondered about float('NaN')? What it is? What you can do with it? What you
shouldn't do with it? Let's take some time and explore this Not a Number and what it does
(and doesn't do) in Python.
Outline
- Introduction. 3 minutes
- Who am I?
- What am I going to talk about?
- What led me to write this talk?
- Introducing
NaN. 3 minutes- What is
NaN? - What purpose does
NaNserve? - The differences beteween
float('nan'),numpy.nan, andmath.nan. - How we can tell if a "numeric" value is NaN.
- What is
- What makes
NaNso unique? 5 minutes- No 2 instances of
NaNare the same. - All instances of
NaNhave the samerepr: "nan" NaNis not equal to anything, not even itself.NaNcan be hashed but each instance ofNaNwill have a different hash.- A set can contain multiple instances of
NaN. - A dictionary can have multiple
NaNkeys, but good luck accessing the data. - If you have an
Iterablewith multiple instances ofNaNand create aCounterfrom it, each instance will appear with a count of 1.
- A set can contain multiple instances of
- No 2 instances of
- Creating a Pythonic
dictthat can only have oneNaN. 12 minutes- Do a code walkthrough and live demo of a Python subclass of
dictthat can only have one instance ofNaN.- Show how I created the new version of
dict. - Simple live demo showing that we can use
float('nan')as a dict key. In a regulardictit will give aKeyErrorwhen attempting to retrieve it; with the new version ofdictit will work as expected.
- Show how I created the new version of
- Do a code walkthrough and live demo of a Python
Counterclass that will count how many instances ofNaNare in it.- Show how I created a
Counterclass that will count all instances ofNaN. - Live demo showing the behaviour of
collections.Counterand the newCounterclass.
- Show how I created a
- Do a code walkthrough and live demo of a Python subclass of
- Conclusion. 2 minutes
- Quick recap of what was discussed.
- Where to find the talk slides.
- Where to find me.
Things I've found
>>> float('nan') ** 0
1.0
>>> float('nan') > 1
False
>>> float('nan') < 1
False
>>> float('nan') == 1
False
>>> float('nan') != 1
True
>>>> float('inf') - float('inf')
nan
>>>> f'ba{1e234567 - 1e765432}as'
'bananas'
import struct
float_bytes = b"\xaa\xbb\xcc\xdd\xff\xff\xff\xff"
val = struct.unpack("d", float_bytes)[0]
print(val)
print(struct.pack("d", val))
In a single precision floating point number (32 bit) there are 2^24 - 2 potential NaN values.
Potential improvements for NaNDict:
- Different types of nans are distinct.
- Perserve the original supplied nan (maybe you do and check_key() does the coalescing).
- A dunder hook for hypothetical future other weird ass values with rogue behaviour like nan.
- An extensive test and performance suite.
- Accept any kind of object for the membership test.
- Accepting unhashable values.
json parsing in Python doesn't handle NaN properly.
pydis
JSON does not represent IEEE-754 floats. It does not permit NaN and infinity as part of the "number" type.
YAML does support NaN
Signed NaN and things with NaN that don't return NaN Jeff Epler
post
From Jeff Epler - NaN Cipher
[math.nan] == [math.nan] is True.
Identity check on the objects before equality check
Issue raised on Python 3.0 about this behaviour
Prior to Python 3.11 CPython did not require IEEE-754
support and included a Py_NO_NAN macro. Current versions of CPython require IEEE-754 support and the macro was removed.
Quotes
NaN is a lot like infinity in that people want to treat it as a number but It's Not and trying to do that will only lead to surprise and disappointment. - Luna Celeste
NaN is a wild land governed by laws both alien and arcane - Luna Celeste
References
https://brassnet.biz/blog/nan-is-weird.html
https://github.com/python/cpython/issues/87641
https://twit.social/@brass75/116168712645625711
https://discuss.python.org/t/question-about-float-nan/106378
Metadata
Release files for nandict 2026.7.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| nandict-2026.7.3.tar.gz | 4.9 kB | With provenance | Details for nandict-2026.7.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| nandict-2026.7.3-py3-none-any.whl | Python 3 | none | any | Details for nandict-2026.7.3-py3-none-any.whl |
Total release size: 11.2 kB
Release files / nandict-2026.7.3.tar.gz
| Download URL | nandict-2026.7.3.tar.gz |
|---|---|
| Size | 4.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a4302ef849829c171d149a532e53f0da72d95a0903e2408cd72ade7115e8fd7f
|
|
BLAKE2b-256 checksum How to use checksums |
0cc3a35b680459543f77a4d3726d3b37f68dab0c8942de1305b0f8acaf1c6d6f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 25, 2026.
Transparency logRelease files / nandict-2026.7.3-py3-none-any.whl
| Download URL | nandict-2026.7.3-py3-none-any.whl |
|---|---|
| Size | 6.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e8cef2093f9d0fa95186562509a6769bb5eadb4b4450de0cb4035caac4d740dd
|
|
BLAKE2b-256 checksum How to use checksums |
80e25f42b73b8d9923269c8d4d039e76679b52a4a39e55719fc0adc8c7230388
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 25, 2026.
Transparency logSecurity for nandict 2026.7.3
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for nandict-2026.7.3.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 25, 2026.
Transparency logA 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.