By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,435 Members | 2,939 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,435 IT Pros & Developers. It's quick & easy.

dict literals vs dict(**kwds)

P: n/a
Although I consider dict(**kwds) as one of the few unfortunate design
choices in python since it prevents the future addition of useful
keyword arguments (e.g a default value or an orderby function), I've
been finding myself lately using it sometimes instead of dict literals,
for no particular reason. Is there any coding style consensus on when
should dict literals be preferred over dict(**kwds) and vice versa ?

George

May 23 '06 #1
Share this Question
Share on Google+
15 Replies


P: n/a
George Sakkis a écrit :
Although I consider dict(**kwds) as one of the few unfortunate design
choices in python since it prevents the future addition of useful
keyword arguments (e.g a default value or an orderby function), I've
been finding myself lately using it sometimes instead of dict literals,
for no particular reason. Is there any coding style consensus on when
should dict literals be preferred over dict(**kwds) and vice versa ?


using dict literals means that you'll always have a builtin dict - you
cannot dynamically select another dict-like class. OTHO, you can only
use valid python identifiers as keys with dict(**kw).
May 23 '06 #2

P: n/a
Bruno Desthuilliers wrote:
George Sakkis a écrit :
Although I consider dict(**kwds) as one of the few unfortunate design
choices in python since it prevents the future addition of useful
keyword arguments (e.g a default value or an orderby function), I've
been finding myself lately using it sometimes instead of dict literals,
for no particular reason. Is there any coding style consensus on when
should dict literals be preferred over dict(**kwds) and vice versa ?


using dict literals means that you'll always have a builtin dict - you
cannot dynamically select another dict-like class. OTHO, you can only
use valid python identifiers as keys with dict(**kw).


This is all good but doesn't answer my original question: under which
circumstances (if any) would {'name':'Mike, 'age':23} be preferred
over dict(name='Mike', age=23) and vice versa, or if it's just a matter
of taste, similar to using single vs double quote for string literals
(when both are valid of course).

George

May 23 '06 #3

P: n/a
George Sakkis <ge***********@gmail.com> wrote:
Bruno Desthuilliers wrote:
George Sakkis a écrit :
Although I consider dict(**kwds) as one of the few unfortunate design
choices in python since it prevents the future addition of useful
keyword arguments (e.g a default value or an orderby function), I've
been finding myself lately using it sometimes instead of dict literals,
for no particular reason. Is there any coding style consensus on when
should dict literals be preferred over dict(**kwds) and vice versa ?


using dict literals means that you'll always have a builtin dict - you
cannot dynamically select another dict-like class. OTHO, you can only
use valid python identifiers as keys with dict(**kw).


This is all good but doesn't answer my original question: under which
circumstances (if any) would {'name':'Mike, 'age':23} be preferred
over dict(name='Mike', age=23) and vice versa, or if it's just a matter
of taste, similar to using single vs double quote for string literals
(when both are valid of course).


My personal favorite style is always to call the type when applicable
(and reasonably forecast to _remain_ applicable in future code changes),
because readability benefits.
Alex
May 24 '06 #4

P: n/a
George Sakkis wrote:
Bruno Desthuilliers wrote:

George Sakkis a écrit :
Although I consider dict(**kwds) as one of the few unfortunate design
choices in python since it prevents the future addition of useful
keyword arguments (e.g a default value or an orderby function), I've
been finding myself lately using it sometimes instead of dict literals,
for no particular reason. Is there any coding style consensus on when
should dict literals be preferred over dict(**kwds) and vice versa ?
using dict literals means that you'll always have a builtin dict - you
cannot dynamically select another dict-like class. OTHO, you can only
use valid python identifiers as keys with dict(**kw).

This is all good but doesn't answer my original question:


I thought it did - at least partly.
under which
circumstances (if any) would {'name':'Mike, 'age':23} be preferred
over dict(name='Mike', age=23)
When you're sure you want a builtin dict (not any other dictlike) and/or
some keys are invalid Python identifiers.
and vice versa,
When all your keys are valid Python identifiers, and you may want to use
another dict-like instead of the builtin dict. It's easy to replace the
dict() factory in a function, class, or whole module :

class MyDict(...):
# dict-like class

dict = MyDict

then all following calls to dict(**kw) in this namespace will use MyDict
instead of the builtin's one. Can't do that with dict litterals.
or if it's just a matter
of taste,
Partly also, but...
similar to using single vs double quote for string literals
(when both are valid of course).


Nope, this is not so similar, cf above.

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
May 24 '06 #5

P: n/a
bruno at modulix wrote:
When all your keys are valid Python identifiers, and you may want to use
another dict-like instead of the builtin dict. It's easy to replace the
dict() factory in a function, class, or whole module :

class MyDict(...):
# dict-like class

dict = MyDict

then all following calls to dict(**kw) in this namespace will use MyDict
instead of the builtin's one. Can't do that with dict litterals.


Hm, as far as I know shadowing the builtins is discouraged. This is not
the same as duck typing, when you may define a function like

def foo(dict_like_class):
return dict_like_class(x=1,y=2).iteritems()

and call it as foo(MyDict)

In either case, I would guess that for the vast majority of cases the
builtin dicts are just fine and there's no compelling reason for
dict(**kwds). Perhaps it's something that should be reconsidered for
Py3K.

George

May 24 '06 #6

P: n/a
> Hm, as far as I know shadowing the builtins is discouraged.

*accidentally* shadowing builtins is a common Python gotcha - that's
why it's comon here to raise *warnings* about this.

Explicitly and knowingly rebinding a builtin (or any other name FWIW)
*with a compatible object* is something else. Just google for
"monkey-patching". And yes, it *is* an application of duck-typing.
In either case, I would guess that for the vast majority of cases the
builtin dicts are just fine
That's probably why there are so many uses of dict-like objects
(starting with the __dict__ attribute of classes, which is usually a
DictProxy object) and so many helpers to build dict-like objects.
and there's no compelling reason for dict(**kwds).
Yes there is : this *is* the ordinary Python syntax - calling a type to
get an instance of it. The dict-litteral syntax is mostly syntactic
sugar.
Perhaps it's something that should be reconsidered for Py3K


Hopefully not. The fact that you fail to understand why a given feature
exists and how it can be useful is not a reason to ask for arbitrary
restrictions on the language.

May 26 '06 #7

P: n/a
bruno de chez modulix en face wrote:
and there's no compelling reason for dict(**kwds).


Yes there is : this *is* the ordinary Python syntax - calling a type to
get an instance of it. The dict-litteral syntax is mostly syntactic
sugar.


The thing is there are four (at least?) ways to get a dict instance:

In [1]: d1={'name':'mike', 'age':23}

In [2]: d2=dict(d1)

In [3]: d3=dict(**d1)

In [4]: d4=dict(d1.items())

In [5]: d1==d2==d3==d4
Out[5]: True

Talk about "there should be one and preferably one obvious way to do
it".

Perhaps it's something that should be reconsidered for Py3K


Hopefully not. The fact that you fail to understand why a given feature
exists and how it can be useful is not a reason to ask for arbitrary
restrictions on the language.


Perhaps you fail to understand that the given feature is
1) redundant (see above).
2) restricting in a more serious sense: the future addition of optional
keyword arguments that affect the dict's behaviour. Google for "default
dict" or "dictionary accumulator".

George

May 26 '06 #8

P: n/a
George Sakkis wrote:
Perhaps you fail to understand that the given feature is
1) redundant (see above).
Yes, but a certain degree of redundancy in the language is inevitable, and
when it exists (as in this case) to make people's life easier it may be a
good thing. Obviously the tradeoff between increasing complexity vs
increasing ease-of-use has to be discussed before such new features are
added, and in this case I believe it was.
2) restricting in a more serious sense: the future addition of optional
keyword arguments that affect the dict's behaviour. Google for "default
dict" or "dictionary accumulator".


There is nothing to stop dictionaries being created using factory functions
(e.g. see dict.fromkeys). So one possible way to implement defaults would
be to extend the dict class with a new classmethod 'withdefault' which
takes a default value as an argument.

However, given that the default argument isn't actually needed during
construction, it doesn't seem to me that it fits either as a constructor
parameter nor a factory method. I don't see why it shouldn't just be set on
an existing dictionary (or dictionary subclass) when you need it.
May 26 '06 #9

P: n/a
Duncan Booth wrote:
George Sakkis wrote:
2) restricting in a more serious sense: the future addition of optional
keyword arguments that affect the dict's behaviour. Google for "default
dict" or "dictionary accumulator".


There is nothing to stop dictionaries being created using factory functions
(e.g. see dict.fromkeys). So one possible way to implement defaults would
be to extend the dict class with a new classmethod 'withdefault' which
takes a default value as an argument.

However, given that the default argument isn't actually needed during
construction, it doesn't seem to me that it fits either as a constructor
parameter nor a factory method. I don't see why it shouldn't just be set on
an existing dictionary (or dictionary subclass) when you need it.


Because I would find

d = dict(default=0)
d['x'] += 3

more elegant than

d = {}
d.withdefault(0)
d['x'] += 3

YMMV,
George

May 26 '06 #10

P: n/a
George Sakkis a écrit :
bruno de chez modulix en face wrote:

and there's no compelling reason for dict(**kwds).
Yes there is : this *is* the ordinary Python syntax - calling a type to
get an instance of it. The dict-litteral syntax is mostly syntactic
sugar.

The thing is there are four (at least?) ways to get a dict instance:

In [1]: d1={'name':'mike', 'age':23}

In [2]: d2=dict(d1)

In [3]: d3=dict(**d1)

In [4]: d4=dict(d1.items())

In [5]: d1==d2==d3==d4
Out[5]: True

Talk about "there should be one and preferably one obvious way to do
it".


This actually makes 2 (two) ways of creating a dict:
- the default call to type (ie : dict(...)
- the syntactic sugar dict-litteral syntax.

The fact that dict() takes either a sequence of pairs and/or keyword
args (yes, you can use both at once) doesn't make for 2 distinct ways.
And the second syntax (litteral) is nothing else than syntaxic sugar -
read : a special case. So if we are to get rid of one or the other, it's
the dict-litteral syntax that should go away.
Perhaps it's something that should be reconsidered for Py3K
Hopefully not. The fact that you fail to understand why a given feature
exists and how it can be useful is not a reason to ask for arbitrary
restrictions on the language.

Perhaps you fail to understand that the given feature is
1) redundant (see above).


see above for an answer on this. FWIW, there are a *lot* of other
syntactic-sugar redundancy in Python. Most of which you're probably not
even aware of.
2) restricting in a more serious sense: the future addition of optional
keyword arguments that affect the dict's behaviour.


This has already been discussed, and IIRC no-one managed to make a
*serious* point about it. The actual signature of dict() is perfectly
sensible for 99% of uses case, and I *never* had a need for "keyword
arguments that affect the dict's behaviour" in 6+ years of Python
programming.

If you want another behaviour, feel free to subclass dict or implement
your own dict-like - FWIW, that's what I do when the need arises.
May 26 '06 #11

P: n/a
Bruno Desthuilliers wrote:
George Sakkis a écrit :
The thing is there are four (at least?) ways to get a dict instance:

In [1]: d1={'name':'mike', 'age':23}

In [2]: d2=dict(d1)

In [3]: d3=dict(**d1)

In [4]: d4=dict(d1.items())

In [5]: d1==d2==d3==d4
Out[5]: True

Talk about "there should be one and preferably one obvious way to do
it".


This actually makes 2 (two) ways of creating a dict:
- the default call to type (ie : dict(...)
- the syntactic sugar dict-litteral syntax.

The fact that dict() takes either a sequence of pairs and/or keyword
args (yes, you can use both at once) doesn't make for 2 distinct ways.
And the second syntax (litteral) is nothing else than syntaxic sugar -
read : a special case. So if we are to get rid of one or the other, it's
the dict-litteral syntax that should go away.
Perhaps it's something that should be reconsidered for Py3K

Hopefully not. The fact that you fail to understand why a given feature
exists and how it can be useful is not a reason to ask for arbitrary
restrictions on the language.

Perhaps you fail to understand that the given feature is
1) redundant (see above).


see above for an answer on this. FWIW, there are a *lot* of other
syntactic-sugar redundancy in Python. Most of which you're probably not
even aware of.


Even without the syntactic-sugar form, I fail to see why you seem to
think that dict(items), dict(otherdict) and dict(**kwds) are all one
thing.
2) restricting in a more serious sense: the future addition of optional
keyword arguments that affect the dict's behaviour.


This has already been discussed, and IIRC no-one managed to make a
*serious* point about it. The actual signature of dict() is perfectly
sensible for 99% of uses case, and I *never* had a need for "keyword
arguments that affect the dict's behaviour" in 6+ years of Python
programming.

If you want another behaviour, feel free to subclass dict or implement
your own dict-like - FWIW, that's what I do when the need arises.


Me too, but I'd gladly toss them if one day dicts were extended to
accept, say a default value or ordering. Plus, adding new functionality
by subclassing often leads to combinatorial explosion (think of "class
OrderedDefaultPrettifiedDict(defaultdict, odict, prettydict)").

George

May 26 '06 #12

P: n/a
George Sakkis wrote:
Duncan Booth wrote:
George Sakkis wrote:
> 2) restricting in a more serious sense: the future addition of
> optional keyword arguments that affect the dict's behaviour. Google
> for "default dict" or "dictionary accumulator".


There is nothing to stop dictionaries being created using factory
functions (e.g. see dict.fromkeys). So one possible way to implement
defaults would be to extend the dict class with a new classmethod
'withdefault' which takes a default value as an argument.

However, given that the default argument isn't actually needed during
construction, it doesn't seem to me that it fits either as a
constructor parameter nor a factory method. I don't see why it
shouldn't just be set on an existing dictionary (or dictionary
subclass) when you need it.


Because I would find

d = dict(default=0)
d['x'] += 3

more elegant than

d = {}
d.withdefault(0)
d['x'] += 3

Well you could have:

d = dict.withdefault(0)

but then you may have to start with an empty dictionary. What happens if
you need to change default for different uses?

Wouldn't wrapping the dictionary in an adaptor be a simpler solution? In
many cases the place where you are going to know what default is
appropriate will be separated from the place where you create the
dictionary. You should be able to write a function which takes a dictionary
as parameter and accumulates values into it.

May 26 '06 #13

P: n/a
Duncan Booth <du**********@invalid.invalid> writes:
d = dict(default=0)
d['x'] += 3

more elegant than

d = {}
d.withdefault(0)
d['x'] += 3

Well you could have:

d = dict.withdefault(0)

but then you may have to start with an empty dictionary. What happens if
you need to change default for different uses?


It might be nice to have something like:

d = {}
...
d.withdefault(0)['x'] += 3

d.withdefault would have to construct some special object whose
__iadd__ did the right thing to make this happen.

This would also let you do stuff like:

d = {}
d0 = d.withdefault(0) # can similarly make d1, d2, etc.
...
d0['x'] += 3
May 26 '06 #14

P: n/a
Duncan Booth wrote:
George Sakkis wrote:
Duncan Booth wrote:
George Sakkis wrote:

> 2) restricting in a more serious sense: the future addition of
> optional keyword arguments that affect the dict's behaviour. Google
> for "default dict" or "dictionary accumulator".

There is nothing to stop dictionaries being created using factory
functions (e.g. see dict.fromkeys). So one possible way to implement
defaults would be to extend the dict class with a new classmethod
'withdefault' which takes a default value as an argument.

However, given that the default argument isn't actually needed during
construction, it doesn't seem to me that it fits either as a
constructor parameter nor a factory method. I don't see why it
shouldn't just be set on an existing dictionary (or dictionary
subclass) when you need it.


Because I would find

d = dict(default=0)
d['x'] += 3

more elegant than

d = {}
d.withdefault(0)
d['x'] += 3

Well you could have:

d = dict.withdefault(0)

but then you may have to start with an empty dictionary. What happens if
you need to change default for different uses?

Wouldn't wrapping the dictionary in an adaptor be a simpler solution? In
many cases the place where you are going to know what default is
appropriate will be separated from the place where you create the
dictionary. You should be able to write a function which takes a dictionary
as parameter and accumulates values into it.


I bet that usually when you create a dictionary, you either populate it
right away or at least you know what kind of items are going to be
added, e.g. "word -> count" or "word -> list of indexes it appears". In
such cases you typically know the default value as well, e.g. 0 or [].
Do you have many use cases where you make a dict without knowing what
is it going to store or where the default might change during the
dict's lifetime ? I can't think of any.

George

May 26 '06 #15

P: n/a
George Sakkis a écrit :
Bruno Desthuilliers wrote:

George Sakkis a écrit :
The thing is there are four (at least?) ways to get a dict instance:
(snip)
This actually makes 2 (two) ways of creating a dict:
- the default call to type (ie : dict(...)
- the syntactic sugar dict-litteral syntax.
(snip)
Even without the syntactic-sugar form, I fail to see why you seem to
think that dict(items), dict(otherdict) and dict(**kwds) are all one
thing.
Of course it's all one thing: a call to a callable that happens to be a
factory for dict instances.
2) restricting in a more serious sense: the future addition of optional
keyword arguments that affect the dict's behaviour.
This has already been discussed, and IIRC no-one managed to make a
*serious* point about it. The actual signature of dict() is perfectly
sensible for 99% of uses case, and I *never* had a need for "keyword
arguments that affect the dict's behaviour" in 6+ years of Python
programming.

If you want another behaviour, feel free to subclass dict or implement
your own dict-like - FWIW, that's what I do when the need arises.

Me too, but I'd gladly toss them if one day dicts were extended to
accept, say a default value or ordering.


Ordering ? What "ordering" ?

Anyway, there's no need to change the actual constructor for this - just
adding a factory would be enough:

d = dict.with_default(default)

But I'm actually -1 on this. I don't like the idea of a dict with
default values for non existing keys.
Plus, adding new functionality
by subclassing often leads to combinatorial explosion
Yes - and this is usually solved with either decorators (the design
pattern - not our beloved @decorators) and/or strategy.

Also, this is more of a statically-typed langages problem. With dynamic
typing, inheritance is only about implementation. Please re-read what I
said : "to subclass dict or implement your own dict-like". There was a
time when subclassing wasn't even an option.
(think of "class
OrderedDefaultPrettifiedDict(defaultdict, odict, prettydict)").


I don't know what is supposed to be a "prettydict". But even if your
monster class is dict-like, it's clearly not a dict no more.

May 26 '06 #16

This discussion thread is closed

Replies have been disabled for this discussion.