I know it's not "fair" to compare language features, but it seems to me
(a Python newbie) that appending a new key/value to a dict in Python is
awfully cumbersome.
In Python, this is the best code I could come up with for adding a new
key, value to a dict
mytable.setdefault( k, [] ).append( v )
In Perl, the code looks like this:
$h{ $key } = $value ;
Is there a better/easier way to code this in Python than the
obtuse/arcane setdefault code? 20 3032
Pat wrote:
I know it's not "fair" to compare language features, but it seems to me
(a Python newbie) that appending a new key/value to a dict in Python is
awfully cumbersome.
In Python, this is the best code I could come up with for adding a new
key, value to a dict
mytable.setdefault( k, [] ).append( v )
In Perl, the code looks like this:
$h{ $key } = $value ;
Is there a better/easier way to code this in Python than the
obtuse/arcane setdefault code?
Naturally, right after writing my post I found that there is an easier way:
table[ k ] = v
I found that in "Python for Dummies". How apropos.
On Oct 13, 7:21*am, Pat <P...@junk.comwrote:
Is there a better/easier way to code this in Python than the
obtuse/arcane setdefault code?
foo = {'bar': 'baz'}
foo.update({'quux': 'blah'})
Pat schrieb:
I know it's not "fair" to compare language features, but it seems to me
(a Python newbie) that appending a new key/value to a dict in Python is
awfully cumbersome.
In Python, this is the best code I could come up with for adding a new
key, value to a dict
mytable.setdefault( k, [] ).append( v )
In Perl, the code looks like this:
$h{ $key } = $value ;
Whats wrong with:
mytable[key] = value
cheers
Paul
Pat wrote:
I know it's not "fair" to compare language features, but it seems to me
(a Python newbie) that appending a new key/value to a dict in Python is
awfully cumbersome.
In Python, this is the best code I could come up with for adding a new
key, value to a dict
mytable.setdefault( k, [] ).append( v )
In Perl, the code looks like this:
$h{ $key } = $value ;
There's a huge difference here:
In your Python example you're using a list. In the Perl example you're
using a scalar value.
Is there a better/easier way to code this in Python than the
obtuse/arcane setdefault code?
When just assigning a new key-value-pair there's no problem in Python.
(Just refer to the answers before.) When I switched from Perl to Python
however I commonly ran into this problem:
>>counter = {} counter['A'] = 1 counter['A'] += 1 counter['A']
2
Ok - assigning a key-value-pair works fine. Incrementing works as well.
>>counter['B'] += 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'B'
However incrementing a non-existing key throws an exception. So you
either have to use a workaround:
>>try:
.... counter['B'] += 1
.... except KeyError:
.... counter['B'] = 1
Since this looks ugly somebody invented the setdefault method:
>>counter['B'] = counter.setdefault('B',0) + 1
And this works with lists/arrays as well. When there's no list yet
setdefault will create an empty list and append the first value.
Otherwise it will just append.
Greetings from Vienna,
mathias
>In Python, this is the best code I could come up with for
>adding a new key, value to a dict
mytable.setdefault( k, [] ).append( v )
Naturally, right after writing my post I found that there is
an easier way:
table[ k ] = v
Just to be clear...these do two VERY different things:
>>v1=42 table1={} k='foo' table1.setdefault(k,[]).append(v1) table2={} table2[k]=v1 table1, table2
({'foo': [42]}, {'foo': 42})
Note that the value in the first case is a *list* while the
value in the 2nd case, the value is a scalar. These differ in
the behavior (continuing from above):
>>v2='Second value' table1.setdefault(k,[]).append(v2) table2[k]=v2 table1, table2
({'foo': [42, 'Second value']}, {'foo': 'Second value'})
Note that table1 now has *two* values associated with 'foo',
while table2 only has the most recently assigned value.
Choose according to your use-case. For some of my ETL &
data-processing work, I often want the
mydict.setdefault(key, []).append(value)
version to accrue values associated with a given unique key.
-tkc
jdd:
foo = {'bar': 'baz'}
foo.update({'quux': 'blah'})
That creates a new dict, to throw it away. Don't do that. Use the
standard and more readable syntax:
foo = {...}
foo['quux'] = 'blah'
Bye,
bearophile
On Mon, 13 Oct 2008 14:10:43 +0200, Mathias Frey wrote:
However incrementing a non-existing key throws an exception. So you
either have to use a workaround:
>>try:
... counter['B'] += 1
... except KeyError:
... counter['B'] = 1
Since this looks ugly somebody invented the setdefault method:
>>counter['B'] = counter.setdefault('B',0) + 1
Nope, for this use case there is the `dict.get()` method:
counter['B'] = counter.get('B', 0) + 1
This assigns only *once* to ``counter['B']`` in every case.
`dict.setdefault()` is for situations where you really want to actually
put the initial value into the dictionary, like with the list example by
the OP.
Ciao,
Marc 'BlackJack' Rintsch be************@lycos.com a écrit :
jdd:
>foo = {'bar': 'baz'} foo.update({'quux': 'blah'})
That creates a new dict, to throw it away.
Just to make it clear for the easily confused ones (like me...):
bearophile is talking about the dict passed as an argument to foo.update
- not about the behaviour of dict.update itself (which of course
modifies the dict in place) !-)
At 2008-10-13T13:14:15Z, be************@lycos.com writes:
jdd:
>foo = {'bar': 'baz'} foo.update({'quux': 'blah'})
That creates a new dict, to throw it away. Don't do that.
I use that if I'm changing many values at once, eg:
foo.update({
'quux': 'blah',
'baz' : 'bearophile',
'jdd' : 'dict',
})
instead of:
foo['quux'] = 'blah'
foo['baz'] = 'bearophile'
foo['jdd'] = 'dict'
because it seems to more clearly indicate what I'm doing, and has fewer
opportunities for types. Still, there is a performance penalty. Running
"my way" 10,000,000 times took 8.7s, and "your way" only took 4.7s. If
you're doing this in an inner loop, that may be significant. While we're on
the subject, use keyword arguments to dict like:
foo.update(dict(quux='blah', baz='bearophile', jdd='dict'))
was *much* slower, at 11.8s.
--
Kirk Strauser
The Day Companies
On Oct 13, 9:41 am, Marc 'BlackJack' Rintsch <bj_...@gmx.netwrote:
On Mon, 13 Oct 2008 14:10:43 +0200, Mathias Frey wrote:
However incrementing a non-existing key throws an exception. So you
either have to use a workaround:
>>try:
... counter['B'] += 1
... except KeyError:
... counter['B'] = 1
Since this looks ugly somebody invented the setdefault method:
>>counter['B'] = counter.setdefault('B',0) + 1
Nope, for this use case there is the `dict.get()` method:
counter['B'] = counter.get('B', 0) + 1
This assigns only *once* to ``counter['B']`` in every case.
`dict.setdefault()` is for situations where you really want to actually
put the initial value into the dictionary, like with the list example by
the OP.
Ciao,
Marc 'BlackJack' Rintsch
....and if you are using Python 2.5 or later you can use the
collections module with collections.defaultdict(list) or
collections.defaultdict(int) to do the same thing. I personally find
it easier to read.
Kirk Strauser wrote:
While we're on
the subject, use keyword arguments to dict like:
foo.update(dict(quux='blah', baz='bearophile', jdd='dict'))
was *much* slower, at 11.8s.
Presumably you would save half of that time by writing simply
foo.update(quux='blah', baz='bearophile', jdd='dict')
Cheers, BB
paul wrote:
Pat schrieb:
>I know it's not "fair" to compare language features, but it seems to me (a Python newbie) that appending a new key/value to a dict in Python is awfully cumbersome.
In Python, this is the best code I could come up with for adding a new key, value to a dict
mytable.setdefault( k, [] ).append( v )
In Perl, the code looks like this:
$h{ $key } = $value ;
Whats wrong with:
mytable[key] = value
cheers
Paul
mytable[key] = value
is the code that I wound up using. It's obvious now that I know the
answer. Thank you very much to all for your help.
In a earlier question (I can't find the thread in my newsreader), I
asked about an array of dict to dict and someone supplied me with the
answer.
[state]={}
[state][city]={}
['Florida']['Tampa] = 20
It worked out perfectly and the Python code is a billion times easier to
read than the Perl version.
Of all the languages I've learned and used professionally, I'm finding
Python to be one of the best languages to learn and use.
Having Wing IDE Pro has made it a lot easier for me to learn and debug.
It does have a few bugs but they always respond by email within
several hours. Absolutely superb customer support. And no, I'm in no
way affiliated with Wingware except that I'm a satisfied customer.
However incrementing a non-existing key throws an exception.
Right. And that's exactly what I would expect, according to the
"principle of least surprise" Python tries to obey. There's simply no
way to increment a non-existent value - not without performing some
obscure implict behind-the-scenes stuff.
So you
either have to use a workaround:
>>try:
... counter['B'] += 1
... except KeyError:
... counter['B'] = 1
Or you could simply use
if counter.has_key('B'):
counter['B'] += 1
else:
counter['B'] = 1
Regards,
Frank
Frank Niemeyer:
There's simply no
way to increment a non-existent value - not without performing some
obscure implict behind-the-scenes stuff.
Like importing and using a defaultdict(int).
So you
either have to use a workaround:
*>>try:
... * counter['B'] += 1
... except KeyError:
... * counter['B'] = 1
Or you could simply use
if counter.has_key('B'):
* * counter['B'] += 1
else:
* * counter['B'] = 1
Both those are slow. Better to use:
if 'B' in counter:
counter['B'] += 1
else:
counter['B'] = 1
Or with a defaultdict:
counter = defauldict(int)
counter['B'] += 1
Bye,
bearophile
On Wed, 22 Oct 2008 10:12:56 -0700, bearophileHUGS wrote:
Frank Niemeyer:
>There's simply no way to increment a non-existent value - not without performing some obscure implict behind-the-scenes stuff.
Like importing and using a defaultdict(int).
So you
either have to use a workaround:
Â*>>try:
... Â* counter['B'] += 1
... except KeyError:
... Â* counter['B'] = 1
Or you could simply use
if counter.has_key('B'): Â* Â* counter['B'] += 1 else: Â* Â* counter['B'] = 1
Both those are slow. Better to use:
if 'B' in counter:
counter['B'] += 1
else:
counter['B'] = 1
Or with a defaultdict:
counter = defauldict(int)
counter['B'] += 1
Or:
counter['B'] = counter.get('B', 0) + 1
Ciao,
Marc 'BlackJack' Rintsch be************@lycos.com schrieb:
Frank Niemeyer:
>There's simply no way to increment a non-existent value - not without performing some obscure implict behind-the-scenes stuff.
Like importing and using a defaultdict(int).
There's nothing implicit in explicitly defining some default behaviour.
Frank
Marc 'BlackJack' Rintsch:
counter['B'] = counter.get('B', 0) + 1
If you benchmark it, you will find that using the get() method it's
quite slower.
Bye,
bearophile
Frank Niemeyer wrote:
>
>However incrementing a non-existing key throws an exception.
Right. And that's exactly what I would expect, according to the
"principle of least surprise" Python tries to obey. There's simply no
way to increment a non-existent value - not without performing some
obscure implict behind-the-scenes stuff.
>So you either have to use a workaround:
> >>try:
... counter['B'] += 1 ... except KeyError: ... counter['B'] = 1
Or you could simply use
if counter.has_key('B'):
counter['B'] += 1
else:
counter['B'] = 1
Regards,
Frank
-- http://mail.python.org/mailman/listinfo/python-list
or
if 'B' in counter:
counter['B'] += 1
else:
ocunter['B'] = 1
--
View this message in context: http://www.nabble.com/Append-a-new-v...p20127415.html
Sent from the Python - python-list mailing list archive at Nabble.com. be************@lycos.com wrote:
Marc 'BlackJack' Rintsch:
>counter['B'] = counter.get('B', 0) + 1
If you benchmark it, you will find that using the get() method it's
quite slower.
Slower than
if 'B' in counter:
counter['B'] += 1
else:
counter['B'] = 1
?
It is not slower than defaultdict which I have compared to
>counter['B'] = counter.get('B', 0) + 1
on a file with 125,000 additions default dict was significantly slower
(only ~40seconds v ~30 secs for get) and used twice the memory.
--
djc
slais-www:
Slower than
...
Okay, I seen there's a little confusion, I try to say it more clearly.
Generally this is the faster version (faster than the version with
get), especially if you use Psyco:
version 1)
if 'B' in counter:
counter['B'] += 1
else:
counter['B'] = 1
-----------------
Version using a defaultdict:
version 2)
counter['B'] += 1 #
The defaultdict case 2) is intermediate: its relative speed changes on
the basis of the frequency of already present keys. Generally the
difference between 1) and 2) isn't much, so I usually use a
defaultdict 2), that has a nicer syntax, even if it can sometimes be a
little slower than 1).
Versions with has_key or try-except or get aren't fast.
Bye,
bearophile This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: tertius |
last post by:
Is there a better way to append certain chars in a string with a
backslash that the example below?
chr = "#$%^&_{}" # special chars to look out for
str = "123 45^ & 00 0_" # string to...
|
by: M. Clift |
last post by:
Hi All,
I have tried to come up with a way to do this myself and all I end up with
is very long code.
What I have is a say item1, item4, item2, item1 etc...
What I want to do is append to...
|
by: Yereth |
last post by:
Hi again,
still working on my xslt program and I ran into another problem. There is a
file which a contains the following structure:
<key>1</key>
<dict>
...
</dict>
<key>2</key>
|
by: Yves Glodt |
last post by:
Hello,
if I do this:
for row in sqlsth:
________pkcolumns.append(row.strip())
________etc
without a prior:
|
by: tonci.tomic |
last post by:
I have IDictionary with integers as keys and values.
Suppose I want to set value for key=42 to 1 if entry doesn't exist in
container. Otherwise, I want to increment value. I ended with:
...
|
by: Yves Glodt |
last post by:
Hi there,
I seem to be unable to find a way to appends more keys/values to the end
of a dictionary... how can I do that?
E.g:
mydict = {'a':'1'}
I need to append 'b':'2' to it to have:
|
by: Niyazi |
last post by:
Hi all,
What is fastest way removing duplicated value from string array using vb.net?
Here is what currently I am doing but the the array contains over 16000
items. And it just do it in 10 or...
|
by: HYRY |
last post by:
I have the following questions, I am using Python 2.4.2
19167152 #1
11306608 #1
1. the address of a.append and list.append is different, can I get the
address of...
|
by: Seongsu Lee |
last post by:
Hi,
I have a dictionary with million keys. Each value in the
dictionary has a list with up to thousand integers.
Follow is a simple example with 5 keys.
dict = {1: ,
2: ,
900000: ,
900001:...
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
| |