Issue #27842: The csv.DictReader now returns rows of type OrderedDict.
This commit is contained in:
parent
15f44ab043
commit
43ca452887
@ -149,18 +149,25 @@ The :mod:`csv` module defines the following classes:
|
|||||||
.. class:: DictReader(csvfile, fieldnames=None, restkey=None, restval=None, \
|
.. class:: DictReader(csvfile, fieldnames=None, restkey=None, restval=None, \
|
||||||
dialect='excel', *args, **kwds)
|
dialect='excel', *args, **kwds)
|
||||||
|
|
||||||
Create an object which operates like a regular reader but maps the
|
Create an object that operates like a regular reader but maps the
|
||||||
information read into a dict whose keys are given by the optional
|
information in each row to an :mod:`OrderedDict <collections.OrderedDict>`
|
||||||
*fieldnames* parameter. The *fieldnames* parameter is a :mod:`sequence
|
whose keys are given by the optional *fieldnames* parameter.
|
||||||
<collections.abc>` whose elements are associated with the fields of the
|
|
||||||
input data in order. These elements become the keys of the resulting
|
The *fieldnames* parameter is a :term:`sequence`. If *fieldnames* is
|
||||||
dictionary. If the *fieldnames* parameter is omitted, the values in the
|
omitted, the values in the first row of the *csvfile* will be used as the
|
||||||
first row of the *csvfile* will be used as the fieldnames. If the row read
|
fieldnames. Regardless of how the fieldnames are determined, the ordered
|
||||||
has more fields than the fieldnames sequence, the remaining data is added as
|
dictionary preserves their original ordering.
|
||||||
a sequence keyed by the value of *restkey*. If the row read has fewer
|
|
||||||
fields than the fieldnames sequence, the remaining keys take the value of
|
If a row has more fields than fieldnames, the remaining data is put in a
|
||||||
the optional *restval* parameter. Any other optional or keyword arguments
|
list and stored with the fieldname specified by *restkey* (which defaults
|
||||||
are passed to the underlying :class:`reader` instance.
|
to ``None``). If a non-blank row has fewer fields than fieldnames, the
|
||||||
|
missing values are filled-in with ``None``.
|
||||||
|
|
||||||
|
All other optional or keyword arguments are passed to the underlying
|
||||||
|
:class:`reader` instance.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.6
|
||||||
|
Returned rows are now of type :class:`OrderedDict`.
|
||||||
|
|
||||||
A short usage example::
|
A short usage example::
|
||||||
|
|
||||||
@ -170,9 +177,11 @@ The :mod:`csv` module defines the following classes:
|
|||||||
... for row in reader:
|
... for row in reader:
|
||||||
... print(row['first_name'], row['last_name'])
|
... print(row['first_name'], row['last_name'])
|
||||||
...
|
...
|
||||||
Baked Beans
|
Eric Idle
|
||||||
Lovely Spam
|
John Cleese
|
||||||
Wonderful Spam
|
|
||||||
|
>>> print(row)
|
||||||
|
OrderedDict([('first_name', 'John'), ('last_name', 'Cleese')])
|
||||||
|
|
||||||
|
|
||||||
.. class:: DictWriter(csvfile, fieldnames, restval='', extrasaction='raise', \
|
.. class:: DictWriter(csvfile, fieldnames, restval='', extrasaction='raise', \
|
||||||
|
@ -11,6 +11,7 @@ from _csv import Error, __version__, writer, reader, register_dialect, \
|
|||||||
__doc__
|
__doc__
|
||||||
from _csv import Dialect as _Dialect
|
from _csv import Dialect as _Dialect
|
||||||
|
|
||||||
|
from collections import OrderedDict
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
|
|
||||||
__all__ = ["QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE",
|
__all__ = ["QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE",
|
||||||
@ -116,7 +117,7 @@ class DictReader:
|
|||||||
# values
|
# values
|
||||||
while row == []:
|
while row == []:
|
||||||
row = next(self.reader)
|
row = next(self.reader)
|
||||||
d = dict(zip(self.fieldnames, row))
|
d = OrderedDict(zip(self.fieldnames, row))
|
||||||
lf = len(self.fieldnames)
|
lf = len(self.fieldnames)
|
||||||
lr = len(row)
|
lr = len(row)
|
||||||
if lf < lr:
|
if lf < lr:
|
||||||
|
@ -10,6 +10,7 @@ import csv
|
|||||||
import gc
|
import gc
|
||||||
import pickle
|
import pickle
|
||||||
from test import support
|
from test import support
|
||||||
|
from itertools import permutations
|
||||||
|
|
||||||
class Test_Csv(unittest.TestCase):
|
class Test_Csv(unittest.TestCase):
|
||||||
"""
|
"""
|
||||||
@ -1092,6 +1093,21 @@ class TestUnicode(unittest.TestCase):
|
|||||||
fileobj.seek(0)
|
fileobj.seek(0)
|
||||||
self.assertEqual(fileobj.read(), expected)
|
self.assertEqual(fileobj.read(), expected)
|
||||||
|
|
||||||
|
class KeyOrderingTest(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_ordering_for_the_dict_reader_and_writer(self):
|
||||||
|
resultset = set()
|
||||||
|
for keys in permutations("abcde"):
|
||||||
|
with TemporaryFile('w+', newline='', encoding="utf-8") as fileobject:
|
||||||
|
dw = csv.DictWriter(fileobject, keys)
|
||||||
|
dw.writeheader()
|
||||||
|
fileobject.seek(0)
|
||||||
|
dr = csv.DictReader(fileobject)
|
||||||
|
kt = tuple(dr.fieldnames)
|
||||||
|
self.assertEqual(keys, kt)
|
||||||
|
resultset.add(kt)
|
||||||
|
# Final sanity check: were all permutations unique?
|
||||||
|
self.assertEqual(len(resultset), 120, "Key ordering: some key permutations not collected (expected 120)")
|
||||||
|
|
||||||
class MiscTestCase(unittest.TestCase):
|
class MiscTestCase(unittest.TestCase):
|
||||||
def test__all__(self):
|
def test__all__(self):
|
||||||
|
@ -64,6 +64,9 @@ Library
|
|||||||
match ``math.inf`` and ``math.nan``, and also ``cmath.infj`` and
|
match ``math.inf`` and ``math.nan``, and also ``cmath.infj`` and
|
||||||
``cmath.nanj`` to match the format used by complex repr.
|
``cmath.nanj`` to match the format used by complex repr.
|
||||||
|
|
||||||
|
- Issue #27842: The csv.DictReader now returns rows of type OrderedDict.
|
||||||
|
(Contributed by Steve Holden.)
|
||||||
|
|
||||||
- Issue #27861: Fixed a crash in sqlite3.Connection.cursor() when a factory
|
- Issue #27861: Fixed a crash in sqlite3.Connection.cursor() when a factory
|
||||||
creates not a cursor. Patch by Xiang Zhang.
|
creates not a cursor. Patch by Xiang Zhang.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user