user3226932 user3226932 - 6 months ago 25
Python Question

Python: assigning variable name versus variable value to dictionary value

Can someone explain why these two different code samples give different outputs? I'm confused on why the first sample appends "sunny" and "cloud" to all months, which is not what I want. I want the output of the second sample. However, I want to assign the variable "forecast", not its value to weatherReport["months"][month]. Is there a way to get the output of Sample 2 this way?

Sample 1:

weatherReport = {"months": {}}


forecast = []

months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]

for month in months[1:]:
weatherReport["months"][month] = forecast

weatherReport["months"]["June"].append("sunny")
weatherReport["months"]["December"].append("cloudy")

print weatherReport


Output for Sample 1:

{'months': {'February': ['sunny', 'cloudy'], 'October': ['sunny', 'cloudy'], 'March': ['sunny', 'cloudy'], 'August': ['sunny', 'cloudy'], 'May': ['sunny', 'cloudy'], 'December': ['sunny', 'cloudy'], 'June': ['sunny', 'cloudy'], 'September': ['sunny', 'cloudy'], 'April': ['sunny', 'cloudy'], 'July': ['sunny', 'cloudy'], 'November': ['sunny', 'cloudy']}}


Sample 2:

weatherReport = {"months": {}}


forecast = []

months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]

for month in months[1:]:
weatherReport["months"][month] = []


weatherReport["months"]["June"].append("sunny")
weatherReport["months"]["December"].append("cloudy")

print weatherReport


Output for Sample 2:

{'months': {'February': [], 'October': [], 'March': [], 'August': [], 'May': [], 'December': ['cloudy'], 'June': ['sunny'], 'September': [], 'April': [], 'July': [], 'November': []}}

Answer

In second code, you assign a brand new independant list for each month. So when you later append values to those lists, you append only to the proper list.

In first code, you assign the same variable to each month. In Python it means that each month has a reference to same list. So when you add a value to any of those list, in reality you add it to the forecast list, to which each month points. So the result.

Under the hood the cause is that a list is mutable, that means that you can modify an object which other objects point to. You will not be able to reproduce that with non mutable objects like strings.