3

I have created a recursive function to fetch the data from a dictionary. The dictionary consists of keys and each key has a list of keys and it goes on. So I need to fetch the flatten list of keys when I give a key input.

My Dict :

data = {"p": ["s1", "s2", "s3", "s4"],
        "s1": ["s1s1", "s1s2"],
        "s2": [],
        "s3": [],
        "s4": [],
        "s1s1": [],
        "s1s2": ["s1s2s1"],
        "s1s2s1": []
        }

My function :

def get_data(key):
    items = data[key]
    if items:
        for key in items:
            items += get_data(key)
    return items

when i call get_data("p") it returns

['s1', 's2', 's3', 's4', 's1s1', 's1s2', 's1s2s1', 's1s2s1']

But the expected output is :

['s1', 's2', 's3', 's4', 's1s1', 's1s2', 's1s2s1']

Thanks in advance for any help ...

4
  • What is items? Commented Feb 27, 2019 at 6:54
  • Question updated Commented Feb 27, 2019 at 6:55
  • @MuthuKumar does the order of the list in which they are present matter? Commented Feb 27, 2019 at 7:00
  • @MuthuKumar Please refer to the answer provided. Commented Feb 27, 2019 at 7:07

2 Answers 2

3

The problem is in these lines -

for key in items:
    items += get_data(key)

Here you are modifying items as you're iterating over it. So in the last iteration, your items ends up getting with the same key multiple times; you can add a logging statement to see which key is being used to call get_data.

You want to obtain all the new items separately, and then update items after the iteration is done -

new_items = []
for key in items:
    new_items += get_data(key)
items += new_items
Sign up to request clarification or add additional context in comments.

Comments

0

Here's a code which will help you achieve what you want. The common approach to get a unique collection of items is to use a set. Sets are unordered collections of distinct objects. To create a set from any iterable, you can simply pass it to the built-in set() function. If you later need a real list again, you can similarly pass the set to the list() function.

data = {"p": ["s1", "s2", "s3", "s4"],
        "s1": ["s1s1", "s1s2"],
        "s2": [],
        "s3": [],
        "s4": [],
        "s1s1": [],
        "s1s2": ["s1s2s1"],
        "s1s2s1": []
        }

def get_data(key):
    items = data[key]
    if items:
        for keys in items:
            items += get_data(keys)
    return list(set(items))

print(get_data("p"))

OUTPUT:

['s3', 's1s1', 's1', 's1s2', 's2', 's1s2s1', 's4']

Update: an order-preserving approach is two lines:

from collections import OrderedDict
return OrderedDict((x, True) for x in items).keys()

replace the return line of the given solution with the return line of the Update: Solution and you will get an ordered list in return.

OUTPUT:

odict_keys(['s1', 's2', 's3', 's4', 's1s1', 's1s2', 's1s2s1'])

Use list() function with the achieved output to get the following list:

['s1', 's2', 's3', 's4', 's1s1', 's1s2', 's1s2s1']

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.