How to create a new typing.Dict[str,str] and add items to it
Asked Answered
C

2

5

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 do not 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. What am I missing or doing incorrectly?

Coelacanth answered 19/4, 2019 at 1:6 Comment(3)
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.Grizelda
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.Acknowledge
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 perspectiveAcknowledge
O
10

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
Obtrude answered 19/4, 2019 at 1:17 Comment(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).Coelacanth
G
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.

Grizelda answered 19/4, 2019 at 1:13 Comment(4)
or more idiomatically, {} ;)Acknowledge
Just wanted to emphasize that dict and Dict are different :)Grizelda
in the same vein, would lists be more commonly specified as () instead of list()?Coelacanth
() is the empty tuple; [] is the empty list. Using the literals is more efficient, as no name lookup is required.Grizelda

© 2022 - 2024 — McMap. All rights reserved.