Skip to content
10 changes: 7 additions & 3 deletions Doc/library/collections.rst
Original file line number Diff line number Diff line change
Expand Up @@ -887,18 +887,22 @@ field names, the method and attribute names start with an underscore.

.. method:: somenamedtuple._asdict()

Return a new :class:`OrderedDict` which maps field names to their corresponding
values:
Return a new ordered dictionary which maps field names to their
corresponding values:

.. doctest::

>>> p = Point(x=11, y=22)
>>> p._asdict()
OrderedDict([('x', 11), ('y', 22)])
{'x': 11, 'y': 22}

.. versionchanged:: 3.1
Returns an :class:`OrderedDict` instead of a regular :class:`dict`.

.. versionchanged:: 3.8
Returns an :class:`dict` instead of a :class:`OrderedDict`,
since it can now keep keys the same order as namedtuple fields.

.. method:: somenamedtuple._replace(**kwargs)

Return a new instance of the named tuple replacing specified fields with new
Expand Down
8 changes: 8 additions & 0 deletions Doc/whatsnew/3.8.rst
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,14 @@ Changes in the Python API
* :class:`uuid.UUID` now uses ``__slots__``, therefore instances can no longer
be weak-referenced and attributes can no longer be added.

* The :meth:`~collections.namedtuple._asdict` method returns a :class:`dict`
instead of :class:`collections.OrderedDict`, because :class:`dict` keeps
insertion order, which is the same behavior as
:class:`collections.OrderedDict`. Anyone relying on
:meth:`~collections.OrderedDict.move_to_end` will want to explicitly construct
an :class:`collections.OrderedDict`.
(Contributed by Michael Selik in :issue:`33463`.)


CPython bytecode changes
------------------------
Expand Down
4 changes: 2 additions & 2 deletions Lib/collections/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -424,8 +424,8 @@ def __repr__(self):
return self.__class__.__name__ + repr_fmt % self

def _asdict(self):
'Return a new OrderedDict which maps field names to their values.'
return OrderedDict(zip(self._fields, self))
'Return a new dict which maps field names to their values.'
return dict(zip(self._fields, self))

def __getnewargs__(self):
'Return self as a plain tuple. Used by copy and pickle.'
Expand Down
1 change: 1 addition & 0 deletions Lib/test/test_collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ def test_instance(self):
self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
self.assertEqual(list(p._asdict()), ['x', 'y']) # test _asdict ordering

try:
p._replace(x=1, error=2)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namedtuple._asdict returns dict instead of OrderedDict, since dict now
keeps keys in insertion order, the same as OrderedDict. Patch by Michael
Selik.