Since when builtin dict preserve key order?

Dan Stromberg drsalists at gmail.com
Sat Mar 24 16:33:27 EDT 2018


On Fri, Mar 23, 2018 at 9:34 PM, Arkadiusz Bulski <arek.bulski at gmail.com> wrote:
> I already asked on PYPY and they confirmed that any version of pypy,
> including 2.7, has dict preserving insertion order. I am familiar with
> ordered **kw which was introduced in 3.6 but I also heard that builtin dict
> preserves order since 3.5. Is that true?

Empirically speaking:
$ cat dict-order
below cmd output started 2018 Sat Mar 24 01:28:15 PM PDT
#!/usr/local/cpython-2.7/bin/python

"""Check if a dictionary appears to have insertion-order preserved."""

n = 10

expected_list = list(range(n - 1, -1, -1))

dict_ = {}
for i in expected_list:
    dict_[i] = 2*i

actual_list = list(dict_)

if actual_list != expected_list:
    raise AssertionError('%s != %s' % (actual_list, expected_list))
above cmd output done    2018 Sat Mar 24 01:28:15 PM PDT
dstromberg at zareason2:~/src/python-tests x86_64-unknown-linux-gnu 15808

$ make
below cmd output started 2018 Sat Mar 24 01:28:18 PM PDT
pythons --file dict-order
/usr/local/cpython-1.0/bin/python (1.0.1) bad
      File "dict-order", line 3
        """Check if a dictionary appears to have insertion-order preserved."""
                                                                           ^
    SyntaxError: invalid syntax
/usr/local/cpython-1.1/bin/python (1.1) bad
    Traceback (innermost last):
      File "dict-order", line 7, in ?
        expected_list = list(range(n - 1, -1, -1))
    NameError: list
/usr/local/cpython-1.2/bin/python (1.2) bad
    Traceback (innermost last):
      File "dict-order", line 7, in ?
        expected_list = list(range(n - 1, -1, -1))
    NameError: list
/usr/local/cpython-1.3/bin/python (1.3) bad
    Traceback (innermost last):
      File "dict-order", line 7, in ?
        expected_list = list(range(n - 1, -1, -1))
    NameError: list
/usr/local/cpython-1.4/bin/python (1.4) bad
    Traceback (innermost last):
      File "dict-order", line 13, in ?
        actual_list = list(dict_)
    TypeError: list() argument must be a sequence
/usr/local/cpython-1.5/bin/python (1.5.2) bad
    Traceback (innermost last):
      File "dict-order", line 13, in ?
        actual_list = list(dict_)
    TypeError: list() argument must be a sequence
/usr/local/cpython-1.6/bin/python (1.6.1) bad
    Traceback (most recent call last):
      File "dict-order", line 13, in ?
        actual_list = list(dict_)
    TypeError: list() argument must be a sequence
/usr/local/cpython-2.0/bin/python (2.0.1) bad
    Traceback (most recent call last):
      File "dict-order", line 13, in ?
        actual_list = list(dict_)
    TypeError: list() argument must be a sequence
/usr/local/cpython-2.1/bin/python (2.1.0) bad
    Traceback (most recent call last):
      File "dict-order", line 13, in ?
        actual_list = list(dict_)
    TypeError: list() argument must be a sequence
/usr/local/cpython-2.2/bin/python (2.2.0) bad
    Traceback (most recent call last):
      File "dict-order", line 16, in ?
        raise AssertionError('%s != %s' % (actual_list, expected_list))
    AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]
/usr/local/cpython-2.3/bin/python (2.3.0) bad
    Traceback (most recent call last):
      File "dict-order", line 16, in ?
        raise AssertionError('%s != %s' % (actual_list, expected_list))
    AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]
/usr/local/cpython-2.4/bin/python (2.4.0) bad
    Traceback (most recent call last):
      File "dict-order", line 16, in ?
        raise AssertionError('%s != %s' % (actual_list, expected_list))
    AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]
/usr/local/cpython-2.5/bin/python (2.5.6) bad
    Traceback (most recent call last):
      File "dict-order", line 16, in <module>
        raise AssertionError('%s != %s' % (actual_list, expected_list))
    AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]
/usr/local/cpython-2.6/bin/python (2.6.9) bad
    Traceback (most recent call last):
      File "dict-order", line 16, in <module>
        raise AssertionError('%s != %s' % (actual_list, expected_list))
    AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]
/usr/local/cpython-2.7/bin/python (2.7.13) bad
    Traceback (most recent call last):
      File "dict-order", line 16, in <module>
        raise AssertionError('%s != %s' % (actual_list, expected_list))
    AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]
/usr/local/cpython-3.0/bin/python (3.0.1) bad
    Traceback (most recent call last):
      File "dict-order", line 16, in <module>
        raise AssertionError('%s != %s' % (actual_list, expected_list))
    AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]
/usr/local/cpython-3.1/bin/python (3.1.5) bad
    Traceback (most recent call last):
      File "dict-order", line 16, in <module>
        raise AssertionError('%s != %s' % (actual_list, expected_list))
    AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]
/usr/local/cpython-3.2/bin/python (3.2.5) bad
    Traceback (most recent call last):
      File "dict-order", line 16, in <module>
        raise AssertionError('%s != %s' % (actual_list, expected_list))
    AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]
/usr/local/cpython-3.3/bin/python (3.3.3) bad
    Traceback (most recent call last):
      File "dict-order", line 16, in <module>
        raise AssertionError('%s != %s' % (actual_list, expected_list))
    AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]
/usr/local/cpython-3.4/bin/python (3.4.2) bad
    Traceback (most recent call last):
      File "dict-order", line 16, in <module>
        raise AssertionError('%s != %s' % (actual_list, expected_list))
    AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]
/usr/local/cpython-3.5/bin/python (3.5.0) bad
    Traceback (most recent call last):
      File "dict-order", line 16, in <module>
        raise AssertionError('%s != %s' % (actual_list, expected_list))
    AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]
/usr/local/cpython-3.6/bin/python (3.6.0) good
/usr/local/cpython-3.7/bin/python (3.7.0b2) good
/usr/local/jython-2.7/bin/jython (2.7.0) bad
    Traceback (most recent call last):
      File "dict-order", line 16, in <module>
        raise AssertionError('%s != %s' % (actual_list, expected_list))
    AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]
/usr/local/pypy-5.10.0/bin/pypy (2.7.13) good
/usr/local/pypy-5.3.1/bin/pypy (2.7.10) good
/usr/local/pypy-5.9.0/bin/pypy (2.7.13) good
/usr/local/pypy3-5.10.0/bin/pypy3 (3.5.3) good
/usr/local/pypy3-5.5.0/bin/pypy3 (3.3.5) good
/usr/local/pypy3-5.8.0-with-lzma-fixes/bin/pypy3 (3.5.3) good
/usr/local/pypy3-5.8.0/bin/pypy3 (3.5.3) good
/usr/local/pypy3-5.9.0/bin/pypy3 (3.5.3) good
/usr/local/micropython-git-2017-06-16/bin/micropython (3.4.0) bad
    Traceback (most recent call last):
      File "dict-order", line 16, in <module>
    AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]

But of course, this doesn't show the fact that order preservation is
present but not guaranteed in 3.6.



More information about the Python-list mailing list