diff --git a/toolz/curried/__init__.py b/toolz/curried/__init__.py index 43aeffd4..c9c90bbb 100644 --- a/toolz/curried/__init__.py +++ b/toolz/curried/__init__.py @@ -59,6 +59,7 @@ assoc_in = toolz.curry(toolz.assoc_in) cons = toolz.curry(toolz.cons) countby = toolz.curry(toolz.countby) +dissoc = toolz.curry(toolz.dissoc) do = toolz.curry(toolz.do) drop = toolz.curry(toolz.drop) excepts = toolz.curry(toolz.excepts) diff --git a/toolz/dicttoolz.py b/toolz/dicttoolz.py index a5f0044a..7ede1f62 100644 --- a/toolz/dicttoolz.py +++ b/toolz/dicttoolz.py @@ -1,4 +1,3 @@ -import copy import operator from toolz.compatibility import (map, zip, iteritems, iterkeys, itervalues, reduce) @@ -197,7 +196,7 @@ def assoc(d, key, value, factory=dict): return d2 -def dissoc(d, *keys): +def dissoc(d, *keys, **kwargs): """ Return a new dict with the given key(s) removed. New dict has d[key] deleted for each supplied key. @@ -210,10 +209,19 @@ def dissoc(d, *keys): >>> dissoc({'x': 1}, 'y') # Ignores missing keys {'x': 1} """ - d2 = copy.copy(d) - for key in keys: - if key in d2: - del d2[key] + factory = _get_factory(dissoc, kwargs) + d2 = factory() + + if len(keys) < len(d) * .6: + d2.update(d) + for key in keys: + if key in d2: + del d2[key] + else: + remaining = set(d) + remaining.difference_update(keys) + for k in remaining: + d2[k] = d[k] return d2 diff --git a/toolz/tests/test_dicttoolz.py b/toolz/tests/test_dicttoolz.py index 0226e49b..d7b78648 100644 --- a/toolz/tests/test_dicttoolz.py +++ b/toolz/tests/test_dicttoolz.py @@ -90,16 +90,16 @@ def test_assoc(self): def test_dissoc(self): D, kw = self.D, self.kw - assert dissoc(D({"a": 1}), "a") == D({}) - assert dissoc(D({"a": 1, "b": 2}), "a") == D({"b": 2}) - assert dissoc(D({"a": 1, "b": 2}), "b") == D({"a": 1}) - assert dissoc(D({"a": 1, "b": 2}), "a", "b") == D({}) - assert dissoc(D({"a": 1}), "a") == dissoc(dissoc(D({"a": 1}), "a"), "a") + assert dissoc(D({"a": 1}), "a", **kw) == D({}) + assert dissoc(D({"a": 1, "b": 2}), "a", **kw) == D({"b": 2}) + assert dissoc(D({"a": 1, "b": 2}), "b", **kw) == D({"a": 1}) + assert dissoc(D({"a": 1, "b": 2}), "a", "b", **kw) == D({}) + assert dissoc(D({"a": 1}), "a", **kw) == dissoc(dissoc(D({"a": 1}), "a", **kw), "a", **kw) # Verify immutability: d = D({'x': 1}) oldd = d - d2 = dissoc(d, 'x') + d2 = dissoc(d, 'x', **kw) assert d is oldd assert d2 is not oldd