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.

Hi, I’m on exercise two, where you have to set a function that loops through the dictionaries in order to get the total sum of profits. The problem is that despite having copied the code as is from the solution itself, python keeps on throwing a type error stating that floats are not iterable. Here’s the code for reference:

def get_profits(input_map):
  total_standard_profit = 0.0
  total_holiday_profit = 0.0
  for key in input_map.keys():
    if 'holiday' in key:
      total_holiday_profit += input_map[key]
    else:
      total_holiday_profit += input_map[key]
  return total_standard_profit 
  return total_holiday_profit

Difficult to say for sure. The function seems a little confused though, you cannot use two return statements in sequence (they’d at least have to be behind logic). As soon as one is met the function finishes. There’s also an unused variable total_standard_profit.

I’d double check how this is written since I don’t think it’ll work the way you expect anyway. Once that’s sorted then have a look at the objects and your types used for a) the loop and b) the += operator.

Thanks for the answer tgrtim. Even fixing the dictionary placement and the return syntax the problem still remains. As for the objects and the types, I believe that everything is alright aside from the fact that the values in the original dictionaries are floats instead of integers, or rather i don’t know what could be wrong

def get_profits(input_map):
  total_standard_profit = 0.0
  total_holiday_profit = 0.0
  for key in input_map.keys():
    if 'holiday' in key:
      total_holiday_profit += input_map[key]
    else:
      total_standard_profit += input_map[key]
  return total_holiday_profit, total_standard_profit```

I can’t see anything wrong with the function so either there’s a problem with the original data or there’s a problem with the created mappings but there’s not enough code to go on.