rsokl/Learning_Python

Defaultdict example does not work (for me)

mgandaman opened this issue · 5 comments

Hello! First of all, thank you for this excellent tutorial! I have been learning Python like stumbling around in a dark room full of dumbbells and this tutorial has helped me immensely so far!

I am on "Data Structures (Part III)" and encountered an issue when I tried running the examples for defaultdict. I cannot get any of them to run. When I run the default code I get an error as follows:

This line (Line 4 in my jupyter notebook cell):
example_default_dict = defaultdict(list) # will map any missing key to list()

Error message:
TypeError: first argument must be callable or None

I am running the code in a Jupyter notebook running Python version 3.7.4. I am unsure what I am doing wrong - is it an issue with my version of Python? The examples I found online indicate that I need to define a variable as a lambda and then use that variable where you have "list" in defaultdict. I am new to this so any help you can provide is much appreciated.

Thank you!

rsokl commented

Hi @mgandaman thank you for taking the time to reach out and troubleshoot this! I am very glad that PLYMI has been helpful so far 😄

There is certainly nothing wrong with your version of Python. I am wondering if perhaps there was a typo in your code when you ran it. Could you double check to see that you didn't accidentally write:

 from collections import defaultdict
 example_default_dict = defaultdict(list())  # note that this is `list()` and not `list`

This indeed will raise the TypeError message that you found.

The difference between passing list and list() is:

  • list is a function (a.k.a a "callable") that defaultdict can use to make lists as-needed for missing key-value pairs.
  • list() (that is calling the list function with no inputs) simply returns an empty list. An empty list is not a function (i.e. not a callable) and thus defaultdict can't use it to create values. Thus it raises the aforementioned TypeError.

And note that, because list is already a callable, there is no need to use lambda anywhere here. A lambda expression is just a convenient way to define one-liner Python functions.

Please let me know if this addresses your issue!

And FYI, in order to include formatted code in a GitHub post, use the formatting:

```python
# your code here
x = 2 + 3
```

Thank you for the help!
Here is the code as I entered it in the notebook:

# demonstrate the behavior of the `defaultdict`
from collections import defaultdict

example_default_dict = defaultdict(list)  # will map any missing key to `list()`
example_default_dict  # an empty default dictionary
defaultdict(list, {})

# "apple" is not a key, so the default mapping "apple" -> list() is created
# and this value is returned
example_default_dict["apple"]

# this mapping now exists in the dictionary
example_default_dict

I've also included a screenshot of the code and the error messages as they appear.
P.S. thanks for the pointers, I'm new to GitHub!
image

rsokl commented

This is strange... Is there any chance that you accidentally overwrote the definition of list in your notebook? Could you try restarting your notebook's kernel and re-running that single cell?

I copied your code as-is and ran it in my notebook without any issue.

Restarting the kernel fixed it! I searched through the notebook and didn't see list defined anywhere, but it seems that was the problem. Thank you!

rsokl commented

Great! Yeah that was a really subtle problem. This is a downside to using Jupyter notebooks: you can write and run code, and then delete it - leaving no trace!

Please share any feedback you have as you continue through PLYMI - I am always looking to improve it!