Skip to main content

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 NaN serve?
    • The differences beteween float('nan'), numpy.nan, and math.nan.
    • How we can tell if a "numeric" value is NaN.
  • What makes NaN so unique? 5 minutes
    • No 2 instances of NaN are the same.
    • All instances of NaN have the same repr: "nan"
    • NaN is not equal to anything, not even itself.
    • NaN can be hashed but each instance of NaN will have a different hash.
      • A set can contain multiple instances of NaN.
      • A dictionary can have multiple NaN keys, but good luck accessing the data.
      • If you have an Iterable with multiple instances of NaN and create a Counter from it, each instance will appear with a count of 1.
  • Creating a Pythonic dict that can only have one NaN. 12 minutes
    • Do a code walkthrough and live demo of a Python subclass of dict that can only have one instance of NaN.
      • 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 regular dict it will give a KeyError when attempting to retrieve it; with the new version of dict it will work as expected.
    • Do a code walkthrough and live demo of a Python Counter class that will count how many instances of NaN are in it.
      • Show how I created a Counter class that will count all instances of NaN.
      • Live demo showing the behaviour of collections.Counter and the new Counter class.
  • 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://xkcd.com/851/

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

https://en.wikipedia.org/wiki/NaN

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nandict-2026.7.3.tar.gz (4.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nandict-2026.7.3-py3-none-any.whl (6.3 kB view details)

Uploaded Python 3

File details

Details for the file nandict-2026.7.3.tar.gz.

File metadata

  • Download URL: nandict-2026.7.3.tar.gz
  • Upload date:
  • Size: 4.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for nandict-2026.7.3.tar.gz
Algorithm Hash digest
SHA256 a4302ef849829c171d149a532e53f0da72d95a0903e2408cd72ade7115e8fd7f
MD5 8dd12f52b25ac5acbba02f58b3a11061
BLAKE2b-256 0cc3a35b680459543f77a4d3726d3b37f68dab0c8942de1305b0f8acaf1c6d6f

See more details on using hashes here.

Provenance

The following attestation bundles were made for nandict-2026.7.3.tar.gz:

Publisher: publish.yml on brass75/nan-talk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nandict-2026.7.3-py3-none-any.whl.

File metadata

  • Download URL: nandict-2026.7.3-py3-none-any.whl
  • Upload date:
  • Size: 6.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for nandict-2026.7.3-py3-none-any.whl
Algorithm Hash digest
SHA256 e8cef2093f9d0fa95186562509a6769bb5eadb4b4450de0cb4035caac4d740dd
MD5 cc0a3712d09ad4aa64f974cdd40fe2b4
BLAKE2b-256 80e25f42b73b8d9923269c8d4d039e76679b52a4a39e55719fc0adc8c7230388

See more details on using hashes here.

Provenance

The following attestation bundles were made for nandict-2026.7.3-py3-none-any.whl:

Publisher: publish.yml on brass75/nan-talk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page