ignerant
ignerant

Reputation: 3

length of list in python

I have a nested configuration dictionary and I need a function to test whether a key exists (up to any level). I came up with this simple function but it fails because on the last item, I end up with just a string and the the len(test) returns the length of the string item. Do I have to change the way I assign all but the first element of test?

conf = {'a':{'b':{'c': [1,2,3]}}}
def has_conf_value(*key_path):
  remaining = conf
  test = key_path
  while len(test) > 1:
    if test[0] in remaining:
      remaining = remaining[test[0]]
      test = test[-1]
    else:
      return False
  return test[0] in remaining

has_conf_value('a','b','c')

I expect True

Upvotes: 0

Views: 144

Answers (1)

modesitt
modesitt

Reputation: 7210

Why not do it recursively

def has_conf_value(conf, *key_path):
    assert len(key_path) > 0
    if len(key_path) == 1:
        return key_path[0] in conf
    if key_path[0] in conf:
        return has_conf_value(conf[key_path[0]], *key_path[1:])
    return False

or

def has_conf_value(conf, *key_path):
    assert len(key_path) > 0
    if len(key_path) == 1:
        return key_path[0] in conf
    return has_conf_value(conf[key_path[0]], *key_path[1:]) if key_path[0] in conf else False

to be briefer. But all you need to change in your original implementation if you want to keep it as similar to the code you currently have is change

test = test[-1]

to

test = test[1:]

or else you are throwing away most of your list. See ShioT's comment below for a more descriptive explanation of why test[-1] is wrong.

Upvotes: 1

Related Questions