473,320 Members | 1,887 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

dict literals vs dict(**kwds)

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
15 2409
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
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
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
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
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
> 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
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
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
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
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
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
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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Paradox | last post by:
Why does the following attempts to pass in keywords arguments not work. It would be alot cooler if there was a way to not have to have the function defined with the variable name. It really seems...
699
by: mike420 | last post by:
I think everyone who used Python will agree that its syntax is the best thing going for it. It is very readable and easy for everyone to learn. But, Python does not a have very good macro...
25
by: Steven Bethard | last post by:
So I end up writing code like this a fair bit: map = {} for key, value in sequence: map.setdefault(key, ).append(value) This code basically constructs a one-to-many mapping -- each value that...
6
by: Rick Morrison | last post by:
Would there be any way to add a method to all dict objects that operated like the .update() method, but also returned a reference to the updated dict? ..update() is clumsy to use inside of list...
49
by: Christopher J. Bottaro | last post by:
I find myself doing the following very often: class Struct: pass .... blah = Struct() blah.some_field = x blah.other_field = y ....
27
by: Ron Adam | last post by:
Hi, I found the following to be a useful way to access arguments after they are passed to a function that collects them with **kwds. class namespace(dict): def __getattr__(self, name): return...
1
by: Luis Zarrabeitia | last post by:
Hi there. I just tried this test: ==== def f(**kwds): print kwds import UserDict d = UserDict.UserDict(hello="world")
6
by: dlists.cad | last post by:
Hi. I am looking for a way to check if some given set of (*args, **kwds) conforms to the argument specification of a given function, without calling that function. For example, given the...
3
by: srinivasan srinivas | last post by:
Hi, I have written a class which has some attributes. I want to know how do i find out the size of an instance of this class?? class T(object):     def __init__(self, fn_name, *args, **kwds):    ...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.