3

There is a great Q/A here already for creating an untyped dictionary in python. I'm struggling to figure out how to create a typed dictionary and then add things to it.

An example of what I am trying to do would be...

return_value = Dict[str,str]
for item in some_other_list:
  if item.property1 > 9:
    return_value.update(item.name, "d'oh")
return return_value

... but this gets me an error of descriptor 'update' requires a 'dict' object but received a 'str'

I've tried a few other permutations of the above declaration

return_value:Dict[str,str] = None

errors with 'NoneType' object has no attribute 'update'. And trying

return_value:Dict[str,str] = dict() 

or

return_value:Dict[str,str] = {}

both error with update expected at most 1 arguments, got 2. I dont know what is needed here to create an empty typed dictionary like I would in c# (var d = new Dictionary<string, string>();). I would rather not eschew type safety if possible. Can someone point out what I'm missing or doing incorrectly?

StingyJack
  • 19,041
  • 10
  • 63
  • 122
  • 4
    `return_value` isn't a `dict`; it's an object that represents the *type* of a `dict`. The things you import from `typing` are *only* for type hints, not actual values. – chepner Apr 19 '19 at 01:08
  • 3
    Note, type annotations **do not give you type safety**. There is no "typed dict" in Python, not built-in anyway. Annotations are for documentation or by use from third-party static time type-checkers, like `mypy`. – juanpa.arrivillaga Apr 19 '19 at 01:24
  • Also, assign a single key-value pair in a `dict`, you do `my_dict[key] = value`. `.update` takes *another mapping*, e.g. another dict, and updates the key-value pairs in the mapping you pass as an argument. So you *could* do `my_dict.update({key:value})` but that is rather wasteful for a single item(creating a completely unnecessary intermediate dict object). Alternatively, you can pass keyword arguments to `.update`, like so: `my_dict.update(foo='bar', baz='bing')` which sometimes is nice from a readability perspective – juanpa.arrivillaga Apr 19 '19 at 01:27

2 Answers2

7

The last 2 ones are the right usage of Dict, but you updated the dictionary with incorrect syntax inside the for loop.

return_value: Dict[str, str] = dict()
for item in some_other_list:
    if item.property1 > 9:
        return_value[item.name] = "d'oh"
return return_value
Pinyi Wang
  • 823
  • 5
  • 14
  • 1
    Thanks, I figured this out about 15 minutes after posting. It only took me a few hours to get to that point =/. The examples for `Dict[]` that I could find had `.update(key,value)`. – StingyJack Apr 19 '19 at 02:58
3

Things like Dict aren't intended to be used at runtime; they are objects that represent types used for static type analysis. If you want a dict, you have to use

return_value = dict()

You can't use Dict to create an object with a restricted runtime type.

chepner
  • 497,756
  • 71
  • 530
  • 681