[Python-ideas] dict.fromkeys() better as dict().setkeys() ? (and other suggestions)
rrr at ronadam.com
Tue May 29 00:49:30 CEST 2007
The dictionary fromkeys method seems out of place as well as miss-named. IMHO
In the current 2.5 branch it occurs only twice. (excluding tests)
$ grep -r "fromkeys" Lib/*.py
Lib/httplib.py: header_names = dict.fromkeys([k.lower() for k in
Lib/UserDict.py: def fromkeys(cls, iterable, value=None):
In httplib.py, it is used as a set to remove duplicates.
There are enough correct uses of it in the wild to keep the behavior, but
it can be done in a better way.
I feel it really should be called set_keys and implemented as a method that
operates on the current dictionary instead of being a constructor for a new
dictionary. That will allow you to add keys with a default value to an
already existing dictionary, or to create a new one with a dictionary
dict().set_keys(s, v=None) # The current fromkeys behavior.
I think this reads better and can be used in a wider variety of situations.
It could be useful for setting an existing dictionary to a default state.
# reset status of items.
Or more likely, resetting a partial sub set of the keys to some initial state.
The reason I started looking at this is I wanted to split a dictionary into
smaller dictionaries and my first thought was that fromkeys would do that.
But of course it doesn't.
What I wanted was to be able to specify the keys and get the values from
the existing dictionary into the new dictionary without using a for loop to
iterate over the keys.
d = dict(1='a', 2='b', 3='c', 4='d', 5='e')
d_odds = d.from_keys([1, 3, 5]) # new dict of items 1, 3, 5
d_evens = d.from_keys([2, 4]) # new dict of items 2, 4
There currently isn't a way to split a dictionary without iterating it's
contents even if you know the keys you need before hand.
A from_keys method would be the inverse complement of the update method.
A del_keys method could replace the clear method. del_keys would be more
useful as it could operate on a partial set of keys.
d.delkeys(d.keys()) # The current clear method behavior.
Some potentially *very common* uses:
# This first one works now, but I included it for completeness. ;-)
""" Combine two dictionaries. """
dd = dict(d1)
""" Split dictionary d using keys. """
keys_rest = set(d.keys()) - set(keys)
return d.from_keys(keys), d.from_keys(keys_rest)
""" Removes and returns a subdict of d with keys. """
dd = d.from_keys(keys)
copy_items(d1, d2, keys):
""" Copy items from dictionary d1 to d2. """
d2.update(d1.from_keys(keys)) # I really like this!
move_items(d1, d2, keys):
""" Move items from dictionary d1 to d2. """
I think the set_keys, from_keys, and del_keys methods could add both
performance and clarity benefits to python.
So to summarize...
1. Replace existing fromkeys method with a set_keys method.
2. Add a partial copy items from_keys method.
3. Replace the clear method with a del_keys method.
So this replaces two methods and adds one more. Overall I think the
usefulness of these would be very good.
I also think it will work very well with the python 3000 keys method
returning an iterator. (And still be two fewer methods than we currently
More information about the Python-ideas