-1

Suppose I have a function that filters out the data like so:

from typing import Dict, Union


def filterData(data: Dict[str, str], fields: Union[list, tuple]) -> dict:

    filteredData = {}

    for field in fields:
        if field in data:
            filteredData[field] = data[field]

    return filteredData

And I use this function like so:

data = filterData({"a": "b", "c": "d"}, ("a")) # This should return {"a": "b"}.

Now, when I try to access a property like data.a, I get an error which says Instance of dict has no member a. How do I define and apply a type which defines all the members of that dictionary?

I tried to create a class,

class ReqData():
    a: str

And then applied to variable like so,

data: ReqData = filterData({"a": "b", "c": "d"}, ("a")

But this didn't work either.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
Axel
  • 4,365
  • 11
  • 63
  • 122
  • 1
    Please clarify. Your ``dict`` *has no* member ``a``. It only has an *item* ``"a"``, i.e. ``data["a"]``. – MisterMiyagi Mar 16 '20 at 16:28
  • it seems you are looking for a dot-dictionary. https://stackoverflow.com/questions/13520421/recursive-dotdict – Pratik Mar 16 '20 at 16:29

2 Answers2

2

This has nothing to do with type annotations and everything with Python dictionary syntax. Unlike JavaScript objects, you cannot use dot notation to access a key in a Python dictionary. Instead you must use bracket notation in the same way you do in your current code:

print(data["a"])

On a side note, you can write your filterData() function in a single line with a dictionary comprehension:

def filterData(data: Dict[str, Union(str, int)], fields: Union[list, tuple]) -> dict:
    return {field : data[field] for field in data if field in fields}
Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • Oops rookie mistake. Thanks! – Axel Mar 16 '20 at 16:28
  • @Sanjay No problem. I just added a oneliner implementation for your `filterData()` function in case you are interested. Note that I iterate over the keys in `data` first. This is more efficient in the case that `fields` contains extra keys that aren't in `data`. – Code-Apprentice Mar 16 '20 at 16:31
  • Thanks for that. But there's a syntax error i think. Square bracket from `field in fields]}` should be removed I guess. – Axel Mar 16 '20 at 16:41
  • @Sanjay Yes, you are correct. Thank you for noticing that. It is fixed now. – Code-Apprentice Mar 16 '20 at 16:45
-2

def filter_data(dd, filters): return { k: v for k, v in dd if k in filters}

print(filter_data({'a': 'avalue', 'b': 'bvalue', 'c': 'cvalue'}, ['a', 'c']))

{'a': 'avalue', 'c': 'cvalue'}

Jesrat
  • 1
  • 1
    Thank you for contributing to Stack Overflow. While this provides a simpler implementation of `filter_data()` it still doesn't answer the OP's question about how to access a single item from the returned dictionary. – Code-Apprentice Mar 16 '20 at 16:31