Re: [Tutor] List methods inside a dictionary of list

2011-07-11 Thread Rafael Turner
I did not understand the behavior of array multiplication. In fact, I
just now learned what it was called thanks to your email.

Best wishes,
Rafael

On Mon, Jul 11, 2011 at 9:33 AM, Brett Ritter  wrote:
> On Mon, Jul 11, 2011 at 9:26 AM, Rafael Turner
>  wrote:
>> I am playing lists and dictionaries and I came across this
>> counter-intuitive result.
>>
> d = dict(zip(['a', 'q', 'c', 'b', 'e', 'd', 'g', 'j'],8*[[0]]))
> ...
> d['a'].__setitem__(0,4)
> ...
>>
>> I was not expecting all the keys to be updated. Is there any
>> documentation I could read on how different datatypes' methods and
>> operators interact differently when inside a dictionary?  I would also
>> like to find a way of being able to use list methods in side a
>> dictionary so that
>
> As has been mentioned, this isn't the dictionary doing anything weird,
> this is that "8*[[0]]" gives you a list of 8 references to the same
> list.  You can play with just that part and see that that's the source
> of your issue.
>
> To achieve what you are trying, try this instead:
>
> d = dict([(x,[0]) for x in ['a', 'q', 'c', 'b', 'e', 'd', 'g', 'j']])
>
> Can you understand how this behaves differently than 8*[[0]] ?  Check
> the Python docs for array multiplication if you're confused, but the
> basic idea is that "[0]" isn't getting evaluated freshly for every
> piece in the array for 8*[[0]], but in a list comprehension it is.
> --
> Brett Ritter / SwiftOne
> swift...@swiftone.org
>
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] List methods inside a dictionary of list

2011-07-11 Thread Brett Ritter
On Mon, Jul 11, 2011 at 9:26 AM, Rafael Turner
 wrote:
> I am playing lists and dictionaries and I came across this
> counter-intuitive result.
>
 d = dict(zip(['a', 'q', 'c', 'b', 'e', 'd', 'g', 'j'],8*[[0]]))
...
 d['a'].__setitem__(0,4)
...
>
> I was not expecting all the keys to be updated. Is there any
> documentation I could read on how different datatypes' methods and
> operators interact differently when inside a dictionary?  I would also
> like to find a way of being able to use list methods in side a
> dictionary so that

As has been mentioned, this isn't the dictionary doing anything weird,
this is that "8*[[0]]" gives you a list of 8 references to the same
list.  You can play with just that part and see that that's the source
of your issue.

To achieve what you are trying, try this instead:

d = dict([(x,[0]) for x in ['a', 'q', 'c', 'b', 'e', 'd', 'g', 'j']])

Can you understand how this behaves differently than 8*[[0]] ?  Check
the Python docs for array multiplication if you're confused, but the
basic idea is that "[0]" isn't getting evaluated freshly for every
piece in the array for 8*[[0]], but in a list comprehension it is.
-- 
Brett Ritter / SwiftOne
swift...@swiftone.org
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] List methods inside a dictionary of list

2011-07-11 Thread Walter Prins
Hi,

On 11 July 2011 14:26, Rafael Turner  wrote:

>
> >>> d = dict(zip(['a', 'q', 'c', 'b', 'e', 'd', 'g', 'j'],8*[[0]]))
> >>>d
> Out:
> {'a': [0],
>  'b': [0],
>  'c': [0],
>  'd': [0],
>  'e': [0],
>  'g': [0],
>  'j': [0],
>  'q': [0]}
>
> >>> d['a'].__setitem__(0,4)
> >>> d
> Out:
> {'a': [4],
>  'b': [4],
>  'c': [4],
>  'd': [4],
>  'e': [4],
>  'g': [4],
>  'j': [4],
>  'q': [4]}
>
> I was not expecting all the keys to be updated. Is there any
> documentation I could read on how different datatypes' methods and
> operators interact differently when inside a dictionary?  I would also
> like to find a way of being able to use list methods in side a
> dictionary so that
>

There's no funny interaction based on datatypes as you imply.  The thing
you're missing is that when you do 8*[[0]], you're actually creating a a
list of references to another **single list** (which happens to contain a
single value, 0.)  Thus, when you then update that single value 0 in that
single list, being pointed to by the several locations in the outer list,
you predictably end up seeing the change from all the references in the
outer list.

To illustrate, do the following:
>>> l=[0]
>>> l2=[l]
>>> l2
[[0]]
>>> l3=8*l2
>>> l3
[[0], [0], [0], [0], [0], [0], [0], [0]]
>>> l[0]=1
>>> l3
[[1], [1], [1], [1], [1], [1], [1], [1]]
>>>

Describing the above:

l is a *single *list object, containing a single value, 0.

l2 is another single list containing this single list l.

l3 is a third list, constructed to by contatenating the* contents* of l2 8
times. This means l3 effectively ends up containing list l (which is the
contents of l2) 8 times in successtion.  *The contents of list l2 is a
reference to list l.*  So consequently in other words each entry in l3 is
actually a back reference to the ***same original list l***.  That is the
key bit to understand, in order to understand why you're seeing what you're
seeing in your example.

Now to illustrate this, we change the original single list l's first element
to something else, namely 1.  And, as expected, when we then view the
apparent contents of l3, as before, it reflects the contents of list l 8
times, because again, every entry in l3 is actually a reference to the same
original list l, which now contains 1 instead of 0.

So, depending on what you're tring to do, you probably want to change your
data structure in your example in some way to ensure you have new seperate
sublists for each entry in your outer list.

Regards

Walter
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] List methods inside a dictionary of list

2011-07-11 Thread Rafael Turner
Hello,

I am playing lists and dictionaries and I came across this
counter-intuitive result.

>>> d = dict(zip(['a', 'q', 'c', 'b', 'e', 'd', 'g', 'j'],8*[[0]]))
>>>d
Out:
{'a': [0],
 'b': [0],
 'c': [0],
 'd': [0],
 'e': [0],
 'g': [0],
 'j': [0],
 'q': [0]}

>>> d['a'].__setitem__(0,4)
>>> d
Out:
{'a': [4],
 'b': [4],
 'c': [4],
 'd': [4],
 'e': [4],
 'g': [4],
 'j': [4],
 'q': [4]}

I was not expecting all the keys to be updated. Is there any
documentation I could read on how different datatypes' methods and
operators interact differently when inside a dictionary?  I would also
like to find a way of being able to use list methods in side a
dictionary so that

>>> d['a'][0] = 5

Does not return

{'a': [5],
 'b': [5],
 'c': [5],
 'd': [5],
 'e': [5],
 'g': [5],
 'j': [5],
 'q': [5]}

But rather

{'a': [5],
 'b': [0],
 'c': [0],
 'd': [0],
 'e': [0],
 'g': [0],
 'j': [0],
 'q': [0]}

Where d is made by d = dict(zip(['a', 'q', 'c', 'b', 'e', 'd', 'g',
'j'],8*[[0]]))

Thanks a bunch,
Rafael
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor