From 915860255a4fe10d89c7a89e7306a220f6b422ec Mon Sep 17 00:00:00 2001 From: Jacobsen Date: Fri, 30 Mar 2018 11:38:44 -0500 Subject: [PATCH 1/7] Fixes #392. --- toolz/dicttoolz.py | 18 ++++++++++++++++++ toolz/tests/test_dicttoolz.py | 15 ++++++++++++--- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/toolz/dicttoolz.py b/toolz/dicttoolz.py index f840e7fc..4c3a05cf 100644 --- a/toolz/dicttoolz.py +++ b/toolz/dicttoolz.py @@ -313,3 +313,21 @@ def get_in(keys, coll, default=None, no_default=False): if no_default: raise return default + + +def select_keys(d, keys, factory=dict): + """ Select only certain keys from a dictionary + + If supplied keys are not found in the dictionary, returns an empty + dictionary. + + >>> d = {'a': 1, 'b': 2, 'c': 3} + >>> select_keys(d, ['a', 'b', 'd']) + {'a': 1, 'b': 2} + >>> select_keys(d, ['c']) + {} + """ + rv = factory() + for k in set(keys).intersection(d.keys()): + rv[k] = d[k] + return rv diff --git a/toolz/tests/test_dicttoolz.py b/toolz/tests/test_dicttoolz.py index 0226e49b..82df54d6 100644 --- a/toolz/tests/test_dicttoolz.py +++ b/toolz/tests/test_dicttoolz.py @@ -1,7 +1,8 @@ from collections import defaultdict as _defaultdict -from toolz.dicttoolz import (merge, merge_with, valmap, keymap, update_in, - assoc, dissoc, keyfilter, valfilter, itemmap, - itemfilter, assoc_in) +from toolz.dicttoolz import (assoc, assoc_in, dissoc, itemfilter, + itemmap, keyfilter, keymap, merge, + merge_with, select_keys, update_in, + valfilter, valmap) from toolz.utils import raises from toolz.compatibility import PY3 @@ -117,6 +118,14 @@ def test_assoc_in(self): assert d is oldd assert d2 is not oldd + def test_select_keys(self): + D, kw = self.D, self.kw + assert select_keys(D({}), [], **kw) == D({}) + assert select_keys(D({"a": 1}), ["a"], **kw) == D({"a": 1}) + assert select_keys(D({"a": 1}), [], **kw) == D({}) + assert select_keys(D({"a": 1}), ["b"], **kw) == D({}) + assert select_keys(D({"a": 1, "b": 2}), ["b"], **kw) == D({"b": 2}) + def test_update_in(self): D, kw = self.D, self.kw assert update_in(D({"a": 0}), ["a"], inc, **kw) == D({"a": 1}) From 84b83201dac9b1855d9dd3de0f1a640623b58ff4 Mon Sep 17 00:00:00 2001 From: Jacobsen Date: Fri, 30 Mar 2018 11:42:22 -0500 Subject: [PATCH 2/7] Fix doctest. --- toolz/dicttoolz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolz/dicttoolz.py b/toolz/dicttoolz.py index 4c3a05cf..4e5ec44c 100644 --- a/toolz/dicttoolz.py +++ b/toolz/dicttoolz.py @@ -324,7 +324,7 @@ def select_keys(d, keys, factory=dict): >>> d = {'a': 1, 'b': 2, 'c': 3} >>> select_keys(d, ['a', 'b', 'd']) {'a': 1, 'b': 2} - >>> select_keys(d, ['c']) + >>> select_keys(d, ['d']) {} """ rv = factory() From a648b7a5a19bd0de3694fb8a90cbad3e39a7739d Mon Sep 17 00:00:00 2001 From: John Jacobsen Date: Mon, 2 Apr 2018 09:09:30 -0500 Subject: [PATCH 3/7] Recommended change to `select_keys`. --- toolz/dicttoolz.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/toolz/dicttoolz.py b/toolz/dicttoolz.py index 4e5ec44c..97f0aa2d 100644 --- a/toolz/dicttoolz.py +++ b/toolz/dicttoolz.py @@ -328,6 +328,7 @@ def select_keys(d, keys, factory=dict): {} """ rv = factory() - for k in set(keys).intersection(d.keys()): - rv[k] = d[k] + for k in keys: + if k in d: + rv[k] = d[k] return rv From a92e45b51874a0290d209f1e88d433d5f9dcd14b Mon Sep 17 00:00:00 2001 From: John Jacobsen Date: Mon, 2 Apr 2018 20:58:42 -0500 Subject: [PATCH 4/7] Use correct URL to fix encoding issue in benchmark test. Fixes #394 (I think). --- bench/test_wordcount.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bench/test_wordcount.py b/bench/test_wordcount.py index cb49fc68..fbf2a0c1 100644 --- a/bench/test_wordcount.py +++ b/bench/test_wordcount.py @@ -2,7 +2,7 @@ import os if not os.path.exists('bench/shakespeare.txt'): - os.system('wget http://www.gutenberg.org/ebooks/100.txt.utf-8' + os.system('wget http://www.gutenberg.org/files/100/100-0.txt' ' -O bench/shakespeare.txt') From aa9a2a7f16c6077e31251724e6226aa3ed811d5f Mon Sep 17 00:00:00 2001 From: John Jacobsen Date: Mon, 2 Apr 2018 21:12:40 -0500 Subject: [PATCH 5/7] Skip order-sensitive doctest for `select_keys`. --- toolz/dicttoolz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolz/dicttoolz.py b/toolz/dicttoolz.py index 97f0aa2d..61192668 100644 --- a/toolz/dicttoolz.py +++ b/toolz/dicttoolz.py @@ -322,7 +322,7 @@ def select_keys(d, keys, factory=dict): dictionary. >>> d = {'a': 1, 'b': 2, 'c': 3} - >>> select_keys(d, ['a', 'b', 'd']) + >>> select_keys(d, ['a', 'b', 'd']) # doctest: +SKIP {'a': 1, 'b': 2} >>> select_keys(d, ['d']) {} From f13de96b4765b287631c421eb4fbb7aa169c446f Mon Sep 17 00:00:00 2001 From: John Jacobsen Date: Fri, 6 Apr 2018 13:12:09 -0500 Subject: [PATCH 6/7] Swap order of args in `select-keys`. --- toolz/dicttoolz.py | 6 +++--- toolz/tests/test_dicttoolz.py | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/toolz/dicttoolz.py b/toolz/dicttoolz.py index 61192668..57412cb6 100644 --- a/toolz/dicttoolz.py +++ b/toolz/dicttoolz.py @@ -315,16 +315,16 @@ def get_in(keys, coll, default=None, no_default=False): return default -def select_keys(d, keys, factory=dict): +def select_keys(keys, d, factory=dict): """ Select only certain keys from a dictionary If supplied keys are not found in the dictionary, returns an empty dictionary. >>> d = {'a': 1, 'b': 2, 'c': 3} - >>> select_keys(d, ['a', 'b', 'd']) # doctest: +SKIP + >>> select_keys(['a', 'b', 'd'], d) # doctest: +SKIP {'a': 1, 'b': 2} - >>> select_keys(d, ['d']) + >>> select_keys(['d'], d) {} """ rv = factory() diff --git a/toolz/tests/test_dicttoolz.py b/toolz/tests/test_dicttoolz.py index 82df54d6..3f8517c5 100644 --- a/toolz/tests/test_dicttoolz.py +++ b/toolz/tests/test_dicttoolz.py @@ -120,11 +120,11 @@ def test_assoc_in(self): def test_select_keys(self): D, kw = self.D, self.kw - assert select_keys(D({}), [], **kw) == D({}) - assert select_keys(D({"a": 1}), ["a"], **kw) == D({"a": 1}) - assert select_keys(D({"a": 1}), [], **kw) == D({}) - assert select_keys(D({"a": 1}), ["b"], **kw) == D({}) - assert select_keys(D({"a": 1, "b": 2}), ["b"], **kw) == D({"b": 2}) + assert select_keys([], D({}), **kw) == D({}) + assert select_keys(["a"], D({"a": 1}), **kw) == D({"a": 1}) + assert select_keys([], D({"a": 1}), **kw) == D({}) + assert select_keys(["b"], D({"a": 1}), **kw) == D({}) + assert select_keys(["b"], D({"a": 1, "b": 2}), **kw) == D({"b": 2}) def test_update_in(self): D, kw = self.D, self.kw From 3fe48aa8bf0ac4dc330fad17e1a56182445af850 Mon Sep 17 00:00:00 2001 From: John Jacobsen Date: Fri, 6 Apr 2018 13:14:16 -0500 Subject: [PATCH 7/7] Add `select_keys` to API doc. --- doc/source/api.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/api.rst b/doc/source/api.rst index f53ff19d..df32b194 100644 --- a/doc/source/api.rst +++ b/doc/source/api.rst @@ -87,6 +87,7 @@ Dicttoolz itemmap merge merge_with + select_keys update_in valfilter valmap