0

I am trying to build a function in order to return true if a key already exist in a dict or any subdict that is part of this dict, i found this solution :

def gen_dict_extract(key, var):
    if hasattr(var,'iteritems'):
        for k, v in var.iteritems():
            if k == key:
                yield v
            if isinstance(v, dict):
                for result in gen_dict_extract(key, v):
                    yield result
            elif isinstance(v, list):
                for d in v:
                    for result in gen_dict_extract(key, d):
                        yield result

but the problem is the result is a generator how to do in order to get true if the key already exist and false if doesn't Thanks

MelDev
  • 275
  • 1
  • 6
  • 18
  • Related: https://stackoverflow.com/questions/14962485/finding-a-key-recursively-in-a-dictionary – Ivan Aksamentov - Drop May 29 '18 at 13:15
  • BTW, that code will only work on Python 2, since `.iteritems` has been renamed to `.items` in Python 3, the old `.items`, which returned a list has been dropped from Python 3. – PM 2Ring May 29 '18 at 13:15
  • You may find the info [here](https://stackoverflow.com/a/41778581/4014959) useful. – PM 2Ring May 29 '18 at 13:17
  • 2
    It would be arguably more straightforward to rewrite this function so it returns a simple True/False value, rather than keeping it as-is and writing an empty-generator-checker. – Kevin May 29 '18 at 13:18
  • https://stackoverflow.com/questions/7460836/how-to-lengenerator One more similar question – rSim May 29 '18 at 13:19
  • Does you dict only contain simple key-value pairs and subdicts, or does it contain lists too? If you don't need to handle lists that code can be simplified. – PM 2Ring May 29 '18 at 13:22

1 Answers1

2

you should use the generator with a single next call in a try/except block and except a StopIteration:

gen = gen_dict_extract("foo", "bar")
try:
    gen.next()
except StopIteration:
    print("this generator is empty")

note that this method will leave "gen" as a generator that already 'yielded' once so you'll need to create another generator to use it.

the best way to use it, of course is to not check whether the generator is empty but handling it's "emptiness" while using it.

Mr. Nun.
  • 775
  • 11
  • 29
  • 3
    But this will also consume and discard the first element. (Of course, if OP only creates the generator in order to see if it's non-empty without planning to use it afterwards, then that's perfectly okay.) – tobias_k May 29 '18 at 13:18
  • 1
    A simpler way to do that, without using `try... except`, is to give `next` an appropriate default arg. – PM 2Ring May 29 '18 at 13:23
  • @tobias_k you are right, and I was editing my post to add that explanation while you posted :) – Mr. Nun. May 29 '18 at 13:25