FAQ: Collections - ChainMap

This community-built FAQ covers the “ChainMap” exercise from the lesson “Collections”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Learn Intermediate Python 3

FAQs on the exercise ChainMap

There are currently no frequently asked questions associated with this exercise – that’s where you come in! You can contribute to this section by offering your own questions, answers, or clarifications on this exercise. Ask or answer a question by clicking reply (reply) below.

If you’ve had an “aha” moment about the concepts, formatting, syntax, or anything else with this exercise, consider sharing those insights! Teaching others and answering their questions is one of the best ways to learn and stay sharp.

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!
You can also find further discussion and get answers to your questions over in #get-help.

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head to #get-help and #community:tips-and-resources. If you are wanting feedback or inspiration for a project, check out #project.

Looking for motivation to keep learning? Join our wider discussions in #community

Learn more about how to use this guide.

Found a bug? Report it online, or post in #community:Codecademy-Bug-Reporting

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

In the third question I try to use a list comprehension to add children to the ChainMap:

[profit_map.new_child(item) for item in new_months_data]

instead of using a loop

for item in new_months_data:
    profit_map = profit_map.new_child(item).

This causes the following notification: " profit_map was not updated correctly with the new data from new_months_data . Expected 15 dictionaries to be stored, but got 12"
It appears no new children are added during the list comprehension. What is causing this behaviour?

From python docs

new_child ( m=None )

Returns a new ChainMap containing a new map followed by all of the maps in the current instance. If m is specified, it becomes the new map at the front of the list of mappings; if not specified, an empty dict is used, so that a call to d.new_child() is equivalent to: ChainMap({}, *d.maps) . This method is used for creating subcontexts that can be updated without altering values in any of the parent mappings.

Sounds to me the return value should be the updated ChainMap…

Apologies for a belated reply but those two operations are not equivalent, .new_child does not operate in place, it creates a new ChainMap.

As an aside that’s really not what a list comp is for, you might raise some eyebrows doing that :scream:

If you’re looking for an alternative you could unpack the new and the old all at once instead of creating several new ChainMap instances and discarding them (anything to save the lovely list comps :wink:).

profit_map = ChainMap(*new_months_data, *profit_map.maps)

I think the order might get a bit funny there (maybe the map itself should be in chronological order from the start, would need to be reversed at present). It might be worth some playing around/testing, especially for months without holiday profit; which year’s holiday profit will then be picked up?

tgrtim
those two operations are not equivalent, .new_child does not operate in place, it creates a new ChainMap

Silly, me that I would miss that. Problem solved.

profit_map = ChainMap(*new_months_data, *profit_map.maps)

Love it. Probably, a fair bit slower, though.

1 Like

I heard that, it happens far too often for me. Slower than creating several new ChainMaps? I’ve not tried but I highly doubt it’s slower, object instantiation is costly. I was surprised there wasn’t a method based alternative for adding multiple dictionaries to the start but I suppose there just wasn’t much need for it. Seems a bit like new_child itself was more of an afterthought for convenience.