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 Language Help.

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

Need broader help or resources? Head to Language Help and Tips and Resources. If you are wanting feedback or inspiration for a project, check out Projects.

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 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?

1 Like

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.

1 Like

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.

I am having the same problem and it is a bit irritating that Codecademy isn’t cleaning up the errors. The exercise even starts off with differend premises, as the variables they hand over are not even called the way they label them in the solution. The cheat sheets are linked but not available, too. I think this course isn’t really finished yet, we’re doing the beta version…

Despite outputting the same result, my solution gives me a “not calculated correctly”

def get_profits(profit_map):
  standard_values = [value for key, value in profit_map.items() if 'holiday' not in key]
  standard_profit = reduce(lambda a, b: a+b, standard_values)
  holiday_values = [value for key, value in profit_map.items() if 'holiday' in key]
  holiday_profit = reduce(lambda a, b: a+b, holiday_values)
  
  return (standard_profit, holiday_profit)

I’ll go with the real solution, but it’s just a bummer

1 Like

After completing this exercise, I’m still in the dark about how ChainMap works, how the new_child method works, and how the parents method works. Anyone have any good resources to better understand this?

Codecademy didn’t do a good job of explaining the concepts. The lesson describes ways to edit a ChainMap but then doesn’t utilize any of those in the exercise. Instead is uses new_child, which wasn’t even an example.

So far I’ve been thoroughly disappointed with the Intermediate Python course…this lesson is no exception.