Help building a dictionary of lists

Joshua Landau joshua.landau.ws at gmail.com
Tue Nov 13 00:41:59 CET 2012


On 12 November 2012 22:26, NJ1706 <nickj1706 at googlemail.com> wrote:

> Chaps,
>
> I am new to Python & have inherited a test harness written in the language
> that I am trying to extend.
>
> The following code shows how dictionaries holding lists of commands are
> handled in the script...
>
> >>> Start of Code_1 <<<

<SNIP>

> >>> End of Output_1 <<<
>
> Note that dict1 contains only the details of the particlare test, see YYY.
>
> This is a very cut down script compared to the real thing & in reality
> there are many more entries in the TestList and also there are many
> dictionaries. To make the script simpler to extend I would like to remove
> the need to manually create each of the dictionaries.
>
> After some reading around I found the dict.fromkeys() method & came up
> with the following...
>
> >>> Start of Code_2 <<<

 <SNIP

> >>> End of Ouput_2 <<<
>
> This almost does what I want but dict2[Test_2] displayed at XXX contains
> the value for Test_1 as well as Test_2. I would be very grateful if someone
> can help me to get the line marked with XXX to be the same as YYY in code_1
> at the start.
>
> I am using Python 2.6.8 on Cygwin 1.7.17 but get the same results on
> CentOS 6.3
>

First of all, thank you for being thorough. It's always a help. *However*,
a minimalistic will be read faster usually, so you may want to crop down
what you have. Additionally, it can result in you solving it yourself!

The problem is as follows

"{1:[], 2:[], 3:[]}" does not equal "dict.fromkeys([1, 2, 3], [])"

You could have worked out this much very quickly, as it is the only thing
you change in the code.

Let's look:
>>> {1:[], 2:[], 3:[]}
{1: [], 2: [], 3: []}
>>> dict.fromkeys([1,2,3], [])
{1: [], 2: [], 3: []}
>>>

Oh no! They are the same! What has happened?
Well, they're *not*. In the first example each of the lists are *unique*:

>>> dct = {1:[], 2:[], 3:[]}
>>> dct[1] is dct[2]
False
>>> dct[1] is dct[3]
False
>>> dct[2] is dct[3]
False
>>>

In the second, they are all *the same list*:

>>> dct = dict.fromkeys([1,2,3], [])
>>> dct[1] is dct[2]
True
>>> dct[1] is dct[3]
True
>>> dct[2] is dct[3]
True
>>>

What does this mean?

>>> a = []
>>> b = []
>>> c = b
>>>
>>> a is b
False
>>> b is c
True
>>>
>>> a.append(1)
>>> b.append(2)
>>> c.append(3)
>>>
>>> a
[1]
>>> b
[2, 3]
>>> c
[2, 3]
>>>

Because b and c in this are *the same*, changing one *is* changing the
other. Hence, you've appended *two* things to b and c, but only one to a.

In your code you use .append on the items in your dict. This will have the
same problem as with a, b and c above.

If you want to make a dict, you can use a dictionary comprehension. I
assume you understand what a list comprehension is. If not, look here:
http://docs.python.org/2/tutorial/datastructures.html#list-comprehensions

Dict comprehension:
{i:[] for i in ["Test 1", "Test 2", "Test 3"]}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20121112/4a4a484a/attachment-0001.html>


More information about the Python-list mailing list