[Tutor] Python Memory Allocation -- deep learning

2018-07-30 Thread Sunil Tech
Hi Team,

I am investigating how the memory allocation happens in Python
For Eg:
*Case 1:*

>>> a = 10
>>> b = 10
>>> c = 10
>>> id(a), id(b), id(c)
(140621897573616, 140621897573616, 140621897573616)
>>> a += 1
>>> id(a)
140621897573592


*Case 2:*

>>> x = 500
>>> y = 500
>>> id(x)
4338740848
>>> id(y)
4338741040


*Case 3:*

>>> s1 = 'hello'
>>> s2 = 'hello'
>>> id(s1), id(s2)
(4454725888, 4454725888)
>>> s1 == s2
True
>>> s1 is s2
True
>>> s3 = 'hello, world!'
>>> s4 = 'hello, world!'
>>> id(s3), id(s4)
(4454721608, 4454721664)
>>> s3 == s4
True
>>> s3 is s4
False

Python memory allocation is varying in all these use cases. Please help me
understand.

Thanks,
Sunil. G
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Python Memory Allocation -- deep learning

2018-07-30 Thread Joel Goldstick
On Mon, Jul 30, 2018 at 9:20 AM, Sunil Tech  wrote:
> Hi Team,
>
> I am investigating how the memory allocation happens in Python
> For Eg:
> *Case 1:*
>
 a = 10
 b = 10
 c = 10
 id(a), id(b), id(c)
> (140621897573616, 140621897573616, 140621897573616)
 a += 1
 id(a)
> 140621897573592
>
>
> *Case 2:*
>
 x = 500
 y = 500
 id(x)
> 4338740848
 id(y)
> 4338741040
>
>
> *Case 3:*
>
 s1 = 'hello'
 s2 = 'hello'
 id(s1), id(s2)
> (4454725888, 4454725888)
 s1 == s2
> True
 s1 is s2
> True
 s3 = 'hello, world!'
 s4 = 'hello, world!'
 id(s3), id(s4)
> (4454721608, 4454721664)
 s3 == s4
> True
 s3 is s4
> False
>
> Python memory allocation is varying in all these use cases. Please help me
> understand.
>
> Thanks,
> Sunil. G
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

An id is not guaranteed to be a memory address.  In the cases you
cited, your version of python caches small integers, and apparently
small strings because its convenient and efficient to do so.  Other
implementations of python may take a different approach.   I think it
would be unwise to ever assume that a value is cached in your day to
day programming

-- 
Joel Goldstick
http://joelgoldstick.com/blog
http://cc-baseballstats.info/stats/birthdays
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Python Memory Allocation -- deep learning

2018-07-30 Thread Mats Wichmann
On 07/30/2018 07:20 AM, Sunil Tech wrote:
> Hi Team,
> 
> I am investigating how the memory allocation happens in Python

There are several things going on here, but the main thing to know is:
but Python language _implementations_ optimize when they can and think
it makes sense. So don't draw too many conclusions from this
experiment... The python.org Python only creates one copy of small
integer objects, I think I've read somewhere the range is -5 to 256.
Strings get some kind of the same treatement - short strings may get
entries in the bytecode generated (.pyc files) allowing references to be
to the same id (id does not necessarily mean memory location, by the way)

Pretty much, don't count on this behavior.  Other Pythons may not do the
same things.

There is some control over whether strings are interned, see sys.intern()



> For Eg:
> *Case 1:*
> 
 a = 10
 b = 10
 c = 10
 id(a), id(b), id(c)
> (140621897573616, 140621897573616, 140621897573616)
 a += 1
 id(a)
> 140621897573592
> 
> 
> *Case 2:*
> 
 x = 500
 y = 500
 id(x)
> 4338740848
 id(y)
> 4338741040
> 
> 
> *Case 3:*
> 
 s1 = 'hello'
 s2 = 'hello'
 id(s1), id(s2)
> (4454725888, 4454725888)
 s1 == s2
> True
 s1 is s2
> True
 s3 = 'hello, world!'
 s4 = 'hello, world!'
 id(s3), id(s4)
> (4454721608, 4454721664)
 s3 == s4
> True
 s3 is s4
> False
> 
> Python memory allocation is varying in all these use cases. Please help me
> understand.
> 
> Thanks,
> Sunil. G
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
> 

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


Re: [Tutor] Python Memory Allocation -- deep learning

2018-07-30 Thread Steven D'Aprano
On Mon, Jul 30, 2018 at 06:50:59PM +0530, Sunil Tech wrote:
> Hi Team,
> 
> I am investigating how the memory allocation happens in Python

You cannot investigate memory allocation in Python code, because the 
Python execution model does not give you direct access to memory.

What you can investigate is:

- when the particular interpreter you are using creates a new
  object, or re-uses an existing object;

- when the particular interpreter you are using re-uses an 
  object ID;

- the *approximate* size of an object in bytes.


Your example #1:

> >>> a = 10
> >>> b = 10
> >>> c = 10
> >>> id(a), id(b), id(c)
> (140621897573616, 140621897573616, 140621897573616)

tells you that the particular interpreter you are using happens to 
re-use the int object 10. This is a version-specific, 
interpreter-specific implementation detail, not a language feature.


Your example #2:

> >>> x = 500
> >>> y = 500
> >>> id(x)
> 4338740848
> >>> id(y)
> 4338741040

shows us that the particular interpreter you are using happens to *not* 
re-use the int object 500, but create a new object each time it is 
required. Again, this is not a language feature.


Your example #3:

> >>> s1 = 'hello'
> >>> s2 = 'hello'
> >>> id(s1), id(s2)
> (4454725888, 4454725888)

tells us that the particular interpreter you are using happens to re-use 
the string object "hello", rather than create two different string 
objects.

Again, this is an implementation feature, not a language feature. 
Another interpreter, or a different version, might behave differently.


> >>> s3 = 'hello, world!'
> >>> s4 = 'hello, world!'
> >>> id(s3), id(s4)
> (4454721608, 4454721664)

And this tells us that the particular interpreter you are using 
*doesn't* re-use the string object "hello, world!" in this context. 

*Everything* you have seen in these examples, with one exception, are 
implementation-specific and depend on the interpreter and the version 
you use, and could change without notice.

The *only* thing you have seen which is a language feature is this rule:

- if two objects, a and b, have the same ID *at the same time*, then 
  "a is b" will be true;

- if "a is b" is false, then a and b must have different IDs.


In practice, most interpreters will follow rules something like this:

- small integers up to some convenient limit, like 20 or 100 or 256, 
  will be cached and re-used;

- integers larger than that will be created as needed;

- small strings that look like identifiers may be cached and re-used;

- large strings and those containing punctuation or spaces probably 
  won't be cached and re-used;

- the interpreter has the right and the ability to change these 
  rules any time it likes.


For example:

py> x = 1.5
py> y = 1.5
py> x is y  # the float object *is not* re-used
False
py> x = 1.5; y = 1.5
py> x is y  # the float object *is* re-used
True



> Python memory allocation is varying in all these use cases.

Nothing in any of those examples shows you anything about memory 
allocation. It only shows you the existence of objects,



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


[Tutor] How to add an Image in Grid mode with Python and Tkinter?

2018-07-30 Thread Matthew Polack
Hi,

Steadily trying to learn Python and Tkinter here with our students...

Am working on a simple 'Price of Cereal Crop' calculatorand have made a
start with the code below...

I'm trying to simply add an image to our program to make the GUI more
interesting...but most of the tutorials describe using the 'Pack'
method not the grid method of layout...

and apparently you cannot use 'Pack' and 'Grid' in the one program...

Can anyone explain how I could add an image to this program? Or show me an
example of a simple program that lets someone simply add an image and use
the grid layout in combination.

Thanks for any clues at all!

- Matt

from tkinter import *
root = Tk("Crop Calculator")

# abutton = Button(root, text="Crop Prices in Australia")

#Main Heading Labels
croplabel = Label(root, text="Crop Prices in Australia", fg="white", bg=
"green")
instruction = Label(root, text="Please select from the following crops", fg=
"green", bg="white")
blanklabel = Label(root, text="", fg="green", bg="white")
blanklabel2 = Label(root, text="", fg="green", bg="white")
statusbar = Label(root, text="Copyright 2018", fg="white", bg="black",
relief='sunken')

#Answerlabel
answerlabel=Label(root, text="wheatwords")

# abutton.pack(side='left', fill='both', expand=True)
croplabel.grid(columnspan=12, sticky='ew')
instruction.grid(row=1, columnspan=12, sticky='ew')
blanklabel.grid(row=2, columnspan=12, sticky='ew')
statusbar.grid(row=12, columnspan=12, sticky='ew')
blanklabel2.grid(row=11, columnspan=12, sticky='ew')


#List of Crops
wheatlabel = Button(root, text="Wheat", fg="black", bg="yellow")
peaslabel = Button(root, text="Peas", fg="white", bg="green")
lupenslabel = Button(root, text="Lupens", fg="white", bg="brown")
barleylabel = Button(root, text="Barley", fg="white", bg="orange")
canolalabel = Button(root, text="Canola", fg="white", bg="red")
sorghumlabel = Button(root, text="Sorghum", fg="white", bg="ivory3")

# Grid positioning of crops.
wheatlabel.grid(row=4, column=1, sticky='ew')
peaslabel.grid(row=4, column=7, sticky='ew')
lupenslabel.grid(row=5, column=1, sticky='ew')
barleylabel.grid(row=5, column=7, sticky='ew')
canolalabel.grid(row=6, column=1, sticky='ew')
sorghumlabel.grid(row=6, column=7, sticky='ew')

# Definitions

def wheatwords():
print("Button one was pushed")

wheatlabel.configure(command=wheatwords)


root.mainloop()

-- 
**Disclaimer: *Whilst every attempt has been made to ensure that material 
contained in this email is free from computer viruses or other defects, the 
attached files are provided, and may only be used, on the basis that the 
user assumes all responsibility for use of the material transmitted. This 
email is intended only for the use of the individual or entity named above 
and may contain information that is confidential and privileged. If you are 
not the intended recipient, please note that any dissemination, 
distribution or copying of this email is strictly prohibited. If you have 
received this email in error, please notify us immediately by return email 
or telephone +61 3 5382 2529** and destroy the original message.*
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Python Memory Allocation -- deep learning

2018-07-30 Thread Max Zettlmeißl via Tutor
On Mon, Jul 30, 2018 at 3:20 PM, Sunil Tech  wrote:
> Python memory allocation is varying in all these use cases. Please help me
> understand.

CPython is interning small integers and small strings as a form of optimisation.

"The current implementation keeps an array of integer objects for all
integers between -5 and 256, when you create an int in that range you
actually just get back a reference to the existing object."

For integers see https://docs.python.org/2/c-api/int.html for Python 2
or https://docs.python.org/3/c-api/long.html for Python 3.

For strings see https://hg.python.org/cpython/file/3.5/Objects/codeobject.c#l51
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Python Memory Allocation -- deep learning

2018-07-30 Thread Steven D'Aprano
On Mon, Jul 30, 2018 at 09:21:01AM -0600, Mats Wichmann wrote:

> (id does not necessarily mean memory location, by the way)

id() *never* means memory location in Python. id() *always* returns an 
opaque integer ID number which has no promised meaning except to be 
unique while the object is alive.

The interpreter has to generate an ID somehow. In Jython and IronPython, 
the interpreter keeps a counter, and IDs are allocated as consecutive 
numbers 1, 2, 3, 4, ... etc. In CPython, the object's memory address is 
used to generate the ID, but the ID does not mean "memory address". If 
the ID happens to match the memory address, that's an accident, not a 
feature of the language.


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


Re: [Tutor] Do something on list elements

2018-07-30 Thread Valerio Pachera
- Messaggio originale -
> Da: "Tutor Python" 
> A: "Tutor Python" 
> Inviato: Sabato, 28 luglio 2018 0:06:55
> Oggetto: Re: [Tutor] Do something on list elements

> But better still is a list comprehension:
> 
> l = [s.replace('X','') for s in l)
> print(l)

Thank you all for the answers.
List comprehension is what I was looking for.

Here's almost the same example that I made up to summarize:

>>> l = ['one ', 'two ', 'three ']
>>> print(l)
['one ', 'two ', 'three ']

>>> l = [ s.strip() for s in l]
>>> print(l)
['one', 'two', 'three']

I create a new list with the same name so I don't need to have another list.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Dictionary viceversa

2018-07-30 Thread Valerio Pachera


Hi all, consider this dictionary

users = {'user1':['office-a', 'office-b'],
 'user2':['office-b'],
 'user3':['office-a','office-c']}

It's a list of users.
For each user there's a list of room it can access to.

Generalizing, a dictionary with a list for each element.

d = {k:list}

I wish to get the same info but "sorted" by room.
In other words, a dictionary that has rooms as keys.
For each room there's a list of users that can access the room.

I've been able to achieve that by

for user in users:
for room in users[user]:
if room in users_by_room:
users_by_room[room].append(user)
else:
users_by_room[room] = []
users_by_room[room].append(user)

And i generalized it in a function like this:

def viceversa(d):
new_d = dict()
for k in d:
for e in d[k]:
if e in new_d:
new_d[e].append(k)
else:
new_d[e] = []
new_d[e].append(k)
return(new_d)

My question is: is there a better way to that?
Maybe by list comprehension?

I was looking to substiture the cicle for e in new_d like this:
  [ new_d[e].append(k) if e in new_d else new_d[e].append(k) for e in d[k] ]
but it can't work because 'new_d[e] = []' is missing.

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


Re: [Tutor] Dictionary viceversa

2018-07-30 Thread Zachary Ware
On Mon, Jul 30, 2018 at 12:20 PM Valerio Pachera  wrote:
> I was looking to substiture the cicle for e in new_d like this:
>   [ new_d[e].append(k) if e in new_d else new_d[e].append(k) for e in d[k] ]
> but it can't work because 'new_d[e] = []' is missing.

Have a look at `dict.setdefault` and play around with it; I think it
will help you do what you want.

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


Re: [Tutor] Dictionary viceversa

2018-07-30 Thread Peter Otten
Zachary Ware wrote:

> On Mon, Jul 30, 2018 at 12:20 PM Valerio Pachera  wrote:
>> I was looking to substiture the cicle for e in new_d like this:
>>   [ new_d[e].append(k) if e in new_d else new_d[e].append(k) for e in
>>   [ d[k] ]
>> but it can't work because 'new_d[e] = []' is missing.
> 
> Have a look at `dict.setdefault` and play around with it; I think it
> will help you do what you want.

Either that, or use a defaultdict:
 
>>> import collections
>>> room_access = collections.defaultdict(list)
>>> for user, rooms in users.items():
... for room in rooms:
... room_access[room].append(user)
... 
>>> room_access
defaultdict(, {'office-c': ['user3'], 'office-b': ['user2', 
'user1'], 'office-a': ['user3', 'user1']})


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


Re: [Tutor] Dictionary viceversa

2018-07-30 Thread Alan Gauld via Tutor
On 30/07/18 13:40, Valerio Pachera wrote:

> users = {'user1':['office-a', 'office-b'],
>  'user2':['office-b'],
>  'user3':['office-a','office-c']}
> 
> It's a list of users.
> For each user there's a list of room it can access to.
> 
> I wish to get the same info but "sorted" by room.

Remember that dicts are not sorted. You can create a dictionary
keyed by room but not sorted by room.
(You can however get a list of sorted keys but that's different,
and you can use a collections.OrderedDict)

> And i generalized it in a function like this:
> 
> def viceversa(d):
> new_d = dict()
> for k in d:
> for e in d[k]:
> if e in new_d:
> new_d[e].append(k)
> else:
> new_d[e] = []
> new_d[e].append(k)
> return(new_d)
> 
> My question is: is there a better way to that?

There are lots of options including those suggested elsewhere.
Another involves using get() which makes your function
look like:

def viceversa(d):
new_d = dict()
for k in d:
for e in d[k]:
new_d[e] = new_d.get(e,[]).append(k)
return(new_d)

> Maybe by list comprehension?

I can't think of a reasonable way of doing that but a
generator may work.

Another option would be to build a set of the original
rooms then iterate over the data, collecting the keys
which have those rooms. But that would be pretty
inefficient...

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


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


Re: [Tutor] Dictionary viceversa

2018-07-30 Thread Zachary Ware
On Mon, Jul 30, 2018 at 1:08 PM Alan Gauld via Tutor  wrote:
> There are lots of options including those suggested elsewhere.
> Another involves using get() which makes your function
> look like:
>
> def viceversa(d):
> new_d = dict()
> for k in d:
> for e in d[k]:
> new_d[e] = new_d.get(e,[]).append(k)

Note that this will set each entry to `None` as returned by `list.append`.

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


Re: [Tutor] How to add an Image in Grid mode with Python and Tkinter?

2018-07-30 Thread Peter Otten
Matthew Polack wrote:

> Hi,
> 
> Steadily trying to learn Python and Tkinter here with our students...
> 
> Am working on a simple 'Price of Cereal Crop' calculatorand have made
> a start with the code below...
> 
> I'm trying to simply add an image to our program to make the GUI more
> interesting...but most of the tutorials describe using the 'Pack'
> method not the grid method of layout...

Open the image with PIL, and then put the image into a Label or Button.
What layout manager you use for that widget afterwords doesn't really 
matter.
 
> and apparently you cannot use 'Pack' and 'Grid' in the one program...
> 
> Can anyone explain how I could add an image to this program? Or show me an
> example of a simple program that lets someone simply add an image and use
> the grid layout in combination.

Let's assume you want to show a picture stored in the file "wheat.jpg" on 
the button with the -- misleading! -- name wheatlabel. Then

> from tkinter import *

from PIL import Image, ImageTk

> root = Tk("Crop Calculator")

# The line above produced an exception over here; I think you wanted

root = Tk() 
root.title("Crop Calculator")

 
> # abutton = Button(root, text="Crop Prices in Australia")
> 
> #Main Heading Labels
> croplabel = Label(root, text="Crop Prices in Australia", fg="white", bg=
> "green")
> instruction = Label(root, text="Please select from the following crops",
> fg= "green", bg="white")
> blanklabel = Label(root, text="", fg="green", bg="white")
> blanklabel2 = Label(root, text="", fg="green", bg="white")
> statusbar = Label(root, text="Copyright 2018", fg="white", bg="black",
> relief='sunken')
> 
> #Answerlabel
> answerlabel=Label(root, text="wheatwords")
> 
> # abutton.pack(side='left', fill='both', expand=True)
> croplabel.grid(columnspan=12, sticky='ew')
> instruction.grid(row=1, columnspan=12, sticky='ew')
> blanklabel.grid(row=2, columnspan=12, sticky='ew')
> statusbar.grid(row=12, columnspan=12, sticky='ew')
> blanklabel2.grid(row=11, columnspan=12, sticky='ew')
> 
> 
> #List of Crops

wheat_image = Image.open("wheat.jpg")
wheat_photo = ImageTk.PhotoImage(wheat_image)

wheatlabel = Button(root, image=wheat_photo, fg="black", bg="yellow")

> peaslabel = Button(root, text="Peas", fg="white", bg="green")
> lupenslabel = Button(root, text="Lupens", fg="white", bg="brown")
> barleylabel = Button(root, text="Barley", fg="white", bg="orange")
> canolalabel = Button(root, text="Canola", fg="white", bg="red")
> sorghumlabel = Button(root, text="Sorghum", fg="white", bg="ivory3")
> 
> # Grid positioning of crops.
> wheatlabel.grid(row=4, column=1, sticky='ew')
> peaslabel.grid(row=4, column=7, sticky='ew')
> lupenslabel.grid(row=5, column=1, sticky='ew')
> barleylabel.grid(row=5, column=7, sticky='ew')
> canolalabel.grid(row=6, column=1, sticky='ew')
> sorghumlabel.grid(row=6, column=7, sticky='ew')
> 
> # Definitions
> 
> def wheatwords():
> print("Button one was pushed")
> 
> wheatlabel.configure(command=wheatwords)
> 
> 
> root.mainloop()
> 


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


Re: [Tutor] How to add an Image in Grid mode with Python and Tkinter?

2018-07-30 Thread Alan Gauld via Tutor
On 30/07/18 08:24, Matthew Polack wrote:

> I'm trying to simply add an image to our program to make the GUI more
> interesting...but most of the tutorials describe using the 'Pack'
> method not the grid method of layout...

That's completely irrelevant since you can add images to widgets
regardless of the layout manager used. In most cases you will
want to use a PhotoImage widget to do it though.

> and apparently you cannot use 'Pack' and 'Grid' in the one program...

Yes you can just not in the same container.
For example a common strategy for building forms based apps
is to have a menubar on top with a toolbar frame packed below
with a data frame packed below that and finally a status
bar frame packed at the bottom.

Within those frames you use the packer for the toolbar buttons,
and for the status bar text. Then you use the grid layout
manager to display the data entry widgets in the centre panel.

So at each container(usually a Frame) level you can only have
a single layout manager, but inside each nested container
you can choose to use the same or a different manager.

And remember there are more than just pack and grid, there
are also place and form(in Tix) (and you can write your own
if you are really keen!)

> Can anyone explain how I could add an image to this program? Or show me an
> example of a simple program that lets someone simply add an image and use
> the grid layout in combination.
import tkinter as tk

top = tk.Tk()
tk.Label(image = "foo.img").grid(row=0,column=0)

top.mainloop)()


Thats about as simple as it gets. But the img file must
be in Tk compatible format.

More generally, use a PhotoImage:

import tkinter as tk

top = tk.Tk()
lbl = tk.Label()
lbl.grid(row=0,column=0)  #could as easily use pack() or place()

img = tk.PhotoImage(file="/path/to/myimg.gif")
lbl['image'] = img

top.mainloop)()

But to get more sophisticated you really want to look
into the PIL/Pillow library and its integration with
Tkinter via the image class. Also look at how the Text
and Canvas widgets deal with images because its slightly
more complex than a simple Label or Button.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


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


Re: [Tutor] Dictionary viceversa

2018-07-30 Thread Alan Gauld via Tutor
On 30/07/18 19:11, Zachary Ware wrote:
> On Mon, Jul 30, 2018 at 1:08 PM Alan Gauld via Tutor  wrote:
>> There are lots of options including those suggested elsewhere.
>> Another involves using get() which makes your function
>> look like:
>>
>> def viceversa(d):
>> new_d = dict()
>> for k in d:
>> for e in d[k]:
>> new_d[e] = new_d.get(e,[]).append(k)
> 
> Note that this will set each entry to `None` as returned by `list.append`.


Oops, yes. You need an intermediate variable:

 for e in d[k]:
 data = new_d.get(e,[])
 data.append(k)
 new_d[e] = data

Or use addition:

 for e in d[k]:
 new_d[e] = new_d.get(e,[]) + [k]


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


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


Re: [Tutor] Python Memory Allocation -- deep learning

2018-07-30 Thread Steven D'Aprano
On Tue, Jul 31, 2018 at 02:58:56AM +1000, Steven D'Aprano wrote:

> The *only* thing you have seen which is a language feature is this rule:
> 
> - if two objects, a and b, have the same ID *at the same time*, then 
>   "a is b" will be true;
> 
> - if "a is b" is false, then a and b must have different IDs.

Sorry, I forgot to mention that for both of those, the reverse applies 
as well. Perhaps a better way to put it is this:

- if "a is b", then a and b must have the same ID, and vice versa.

- if "a is not b", then a and b must have different IDs, and vice versa.



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