0

Is it possible to just use .get() function from dictionary for this? Is this the best we can do to shorten this piece of code?

n_dict is a Dict type (uppercase D) and NES is just a list of str

eted_info = {}
for key in n_dict:
    if key in NES:
        eted_info[key] = n_dict[key]

I'm just curious if there is a better / more pythonic way to retrieve a value, like C# has with TryGetValue.

martineau
  • 119,623
  • 25
  • 170
  • 301
caasswa
  • 501
  • 3
  • 10

4 Answers4

5

I think a dictionary comprehension and using n_dict.items() is the cleanest way of doing this

n_dict = {'a': 1, 'b': 2, 'c': 3}

NES = ['a', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']

eted_info = {key:value for key,value in n_dict.items() if key in NES}

print(eted_info)

RESULT

{'a': 1, 'c': 3}
Chris
  • 26,361
  • 5
  • 21
  • 42
Buddy Bob
  • 5,829
  • 1
  • 13
  • 44
2

You can do something with dictionary comprehension like this:

eted_info = {key: n_dict[key] for key in n_dict if key in NES}
Andrew Wei
  • 870
  • 1
  • 7
  • 12
  • thanks man, that definitely looks better :) is there any performance difference? – caasswa Dec 14 '21 at 01:52
  • It is slightly faster, but not by much in most cases: https://stackoverflow.com/questions/52542742/why-is-this-loop-faster-than-a-dictionary-comprehension-for-creating-a-dictionar – Andrew Wei Dec 14 '21 at 01:59
  • 1
    Slight variation using `items()`: `eted_info = {k: v for k, v in n_dict.items() if k in NES}` – Samwise Dec 14 '21 at 02:05
  • 1
    Another using sets (might be more performant if `NES` and `ndict` are very large, since it avoids O(n^2) lookups): `eted_info = {k: n_dict[k] for k in set(n_dict) & set(NES)}` – Samwise Dec 14 '21 at 02:06
  • 1
    @Samwise Would you mind posting that second one as an answer? I don't find it as readable for likely use, but as you said, for very large `NES` and `ndict`, it's quite slick. – CrazyChucky Dec 14 '21 at 02:19
2

If you want to avoid the O(n^2) operation of iterating through each item in NES for each item in n_dict, you can build a list of keys as a set intersection and iterate through that:

eted_info = {k: n_dict[k] for k in set(n_dict) & set(NES)}
Samwise
  • 68,105
  • 3
  • 30
  • 44
1

Iterate over keys in NES; use n_dict.get.get with a default of None; conditionally add to eted_info.

for key in NES:
    v = n_dict.get(key,None)
    if v: eted_info[key] = v
  • This will only iterate over the list once regardless of the length of n_dict.
  • Assumes all values in n_dict are truthy. Other placeholders could be used for the default value.
wwii
  • 23,232
  • 7
  • 37
  • 77
  • You could write that as a dict-comprehension:: eted_info = {key:n_dict[key] for key in NES if key in n_dict} Pretty much the same as @AndrewWei but the small difference saves a bit of complexity. – Anne Aunyme Dec 14 '21 at 02:26
  • @AnneAunyme - yes you could! Feel free to add (edit) that to my answer. – wwii Dec 14 '21 at 15:10