From e8e66f779e5e760c7049e203c89001879c25dbd1 Mon Sep 17 00:00:00 2001 From: Michael Selik Date: Fri, 29 Jun 2018 12:54:30 -0700 Subject: [PATCH 1/5] Use dict instead of OrderedDict DictReader can now use basic dicts instead of OrderedDict, as of version 3.7's change to specify that dict maintains keys in insertion order. This will be more efficient and more pleasant to read at the interactive prompt. I also changed a list comprehension to a generator expression inside of a ``", ".join()`` to avoid the unnecessary list construction. --- Lib/csv.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Lib/csv.py b/Lib/csv.py index 58624af9053493..62684322d1a364 100644 --- a/Lib/csv.py +++ b/Lib/csv.py @@ -11,7 +11,6 @@ __doc__ from _csv import Dialect as _Dialect -from collections import OrderedDict from io import StringIO __all__ = ["QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE", @@ -117,7 +116,7 @@ def __next__(self): # values while row == []: row = next(self.reader) - d = OrderedDict(zip(self.fieldnames, row)) + d = dict(zip(self.fieldnames, row)) lf = len(self.fieldnames) lr = len(row) if lf < lr: @@ -148,7 +147,7 @@ def _dict_to_list(self, rowdict): wrong_fields = rowdict.keys() - self.fieldnames if wrong_fields: raise ValueError("dict contains fields not in fieldnames: " - + ", ".join([repr(x) for x in wrong_fields])) + + ", ".join(repr(x) for x in wrong_fields)) return (rowdict.get(key, self.restval) for key in self.fieldnames) def writerow(self, rowdict): From 38b7b3c277044ffea538305f1e626ef0365cc2c1 Mon Sep 17 00:00:00 2001 From: Michael Selik Date: Fri, 29 Jun 2018 13:05:17 -0700 Subject: [PATCH 2/5] blurb add --- .../next/Library/2018-06-29-13-05-01.bpo-34003.Iu831h.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2018-06-29-13-05-01.bpo-34003.Iu831h.rst diff --git a/Misc/NEWS.d/next/Library/2018-06-29-13-05-01.bpo-34003.Iu831h.rst b/Misc/NEWS.d/next/Library/2018-06-29-13-05-01.bpo-34003.Iu831h.rst new file mode 100644 index 00000000000000..7bc5e1200ae806 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-29-13-05-01.bpo-34003.Iu831h.rst @@ -0,0 +1,2 @@ +csv.DictReader now creates dicts instead of OrderedDicts. Patch by Michael +Selik. From 14f2164fce2dd35764beae4d2e082df836817648 Mon Sep 17 00:00:00 2001 From: Michael Selik Date: Fri, 29 Jun 2018 13:22:27 -0700 Subject: [PATCH 3/5] fix documentation, DictReader now yields dicts --- Doc/library/csv.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst index 049537eff89846..ccecb9c2b45033 100644 --- a/Doc/library/csv.rst +++ b/Doc/library/csv.rst @@ -150,12 +150,12 @@ The :mod:`csv` module defines the following classes: dialect='excel', *args, **kwds) Create an object that operates like a regular reader but maps the - information in each row to an :mod:`OrderedDict ` - whose keys are given by the optional *fieldnames* parameter. + information in each row to a ``dict`` whose keys are given by the optional + *fieldnames* parameter. The *fieldnames* parameter is a :term:`sequence`. If *fieldnames* is omitted, the values in the first row of file *f* will be used as the - fieldnames. Regardless of how the fieldnames are determined, the ordered + fieldnames. Regardless of how the fieldnames are determined, the dictionary preserves their original ordering. If a row has more fields than fieldnames, the remaining data is put in a @@ -166,8 +166,8 @@ The :mod:`csv` module defines the following classes: 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`. + .. versionchanged:: 3.8 + Returned rows are now of type :class:`dict`. A short usage example:: @@ -181,7 +181,7 @@ The :mod:`csv` module defines the following classes: John Cleese >>> print(row) - OrderedDict([('first_name', 'John'), ('last_name', 'Cleese')]) + {'first_name': 'John', 'last_name': 'Cleese'} .. class:: DictWriter(f, fieldnames, restval='', extrasaction='raise', \ From bcea2a433ff2271c8e5ef05bc3aa37b25efaccab Mon Sep 17 00:00:00 2001 From: Michael Selik Date: Fri, 29 Jun 2018 13:34:38 -0700 Subject: [PATCH 4/5] use rST metadata for class ref --- Doc/library/csv.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst index ccecb9c2b45033..17534fcc4615dc 100644 --- a/Doc/library/csv.rst +++ b/Doc/library/csv.rst @@ -150,8 +150,8 @@ The :mod:`csv` module defines the following classes: dialect='excel', *args, **kwds) Create an object that operates like a regular reader but maps the - information in each row to a ``dict`` whose keys are given by the optional - *fieldnames* parameter. + information in each row to a :class:`dict` whose keys are given by the + optional *fieldnames* parameter. The *fieldnames* parameter is a :term:`sequence`. If *fieldnames* is omitted, the values in the first row of file *f* will be used as the From 0b4c14340b95f77fcc4df1be00f589a536c27cb2 Mon Sep 17 00:00:00 2001 From: Michael Selik Date: Sat, 30 Jun 2018 11:59:08 -0700 Subject: [PATCH 5/5] revert to list comprehension str.join creates a list internally if the input is not a list or tuple. Passing a generator expression only adds overhead. --- Lib/csv.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/csv.py b/Lib/csv.py index 62684322d1a364..eeeedabc6bb8a2 100644 --- a/Lib/csv.py +++ b/Lib/csv.py @@ -147,7 +147,7 @@ def _dict_to_list(self, rowdict): wrong_fields = rowdict.keys() - self.fieldnames if wrong_fields: raise ValueError("dict contains fields not in fieldnames: " - + ", ".join(repr(x) for x in wrong_fields)) + + ", ".join([repr(x) for x in wrong_fields])) return (rowdict.get(key, self.restval) for key in self.fieldnames) def writerow(self, rowdict):