Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Added DefaultDict #3

Merged
merged 2 commits into from
Dec 1, 2013
Merged

Conversation

kmsquire
Copy link
Member

This is a DefaultDict implementation which mimics the Python implementation of the same.

Need to add docs and tests, but the basics are here.

Now includes docs and tests.

Some examples (from my updates to the README):

## Constructors
DefaultDict(default, d::Associative=Dict())  # create a DefaultDict with a default value or function,
                                             # optionally wrapping an existing dictionary
DefaultDict(KeyType, ValueType, default)     # create a DefaultDict with Dict type (KeyType,ValueType)

# Examples
dd = DefaultDict(1)               # create an (Any=>Any) DefaultDict with a default value of 1
dd = DefaultDict(String, Int, 0)  # create a (String=>Int) DefaultDict with a default value of 0

d = ['a'=>1, 'b'=>2]
dd = DefaultDict(0, d)            # provide a default value to an existing dictionary
dd['c'] == 0                      # true
d['c']  == 0                      # true

dd = DefaultDict(time)            # call time() to provide the default value
dd = DefaultDict(Dict)            # Create a dictionary of dictionaries
                                  # Dict() is called to provide the default value
dd = DefaultDict(()->myfunc())    # call function myfunc to provide the default value

# create a Dictionary of String=>DefaultDict{String, Int}, where the default of the
# inner set of DefaultDicts is zero
dd = DefaultDict(String, DefaultDict, ()->DefaultDict(String,Int,0))

I could make a separate package if that is preferable, but this does seem to at least go with the Accumulator/Counter type (and in fact, could provide an alternate implementation of those). The coding/writing style might be slightly different, so I'm open to any thought/suggestions.

* allow DefaultDicts to wrap any Associative type
* added tests
* added documentation
@kmsquire
Copy link
Member Author

@lindahua, I've updated this request, and I think it's complete. Let me know what you think.

# If the Dict implementation changes, this may break.
# Also note that we hash twice here if the key is not in the dictionary: once
# when retrieving, and once when assigning.
function getindex{K,V,F<:Base.Callable}(d::DefaultDict{K,V,F}, key)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not simply use getindex(d::DefaultDict, key) = get(d, key, d.default)? Isn't this the whole point of get?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As of right now, get doesn't modify the dictionary if a key doesn't exist, but getindex does.

I'm mimicking Python here. I think that choosing whether or not get modifies the dictionary is arbitrary, and I couldn't think of a good argument against the python implementation. Well, other than the fact that getindex isn't as efficient... Hmm.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, unless we don't modify the dictionary at all, simply calling get wouldn't change much, as the logic in this function would then move to get. The main thing getting in the way of simplifying all of this is that we only want to call d.default() when the value is not in the dictionary.

Abstractly, what would be useful is a function which, e.g, returns a token that indicates whether or not a key is in the dictionary, as well as indicating (to the dictionary) the location of the key if it exists, or where it would go if it doesn't exist. Making such a function public would allow hash values to be returned to the caller.

@lindahua
Copy link
Contributor

lindahua commented Dec 1, 2013

@kmsquire This looks great to me.

I granted the commit privilege to you. Please merge it when you think it is ready.

@kmsquire
Copy link
Member Author

kmsquire commented Dec 1, 2013

Thanks, Dahua. I think it's good to go for now. Cheers!

kmsquire added a commit that referenced this pull request Dec 1, 2013
@kmsquire kmsquire merged commit 3d21cee into JuliaCollections:master Dec 1, 2013
@kmsquire kmsquire deleted the defaultdict branch December 1, 2013 05:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants