Home > OS >  To retrieve data from list where it contains dictionary as its values (python)
To retrieve data from list where it contains dictionary as its values (python)

Time:05-21

I am newbie to python, trying to understand the concepts. I am trying to traverse a list, where inside list, I have kept dictionary data set which are initialized. I have defined function to traverse and the retrieve data.

Initially first key and value will be assigned to activeConfiguration list i,e activeConfiguration = ['Mammals','dogs'] and this activeConfiguration is passed as an param for getNextConfig(data, activeConfiguration) function along with entity data.

My goal is that after some certain steps when I make function call getNextConfig(data, activeConfiguration) it should retrieve next value for from the list for the particular key. the expected out I have specified below.

My code has bug, please help me to fix and to get desired result. Thanks for the help in advance.

#Entity data initialization

vertebrateAnimalsDict = [
   
    {
        "Reptiles": "Snakes, lizards, crocodiles, alligators, turtles"
    },
    
    {
        "Mammals": "dogs, cats, horses, duckbill platypuses, kangaroos, dolphins, whales"
    },

    {
        "Minibeasts": "Insects, spiders, crustaceans"
    }
]

My function calls :

activeConfiguration = ['Mammals','dogs']

activeConfiguration = getNextConfig(vertebrateAnimalsDict, activeConfiguration)
print(activeConfiguration)

#some tasks in between
 ...
activeConfiguration = getNextConfig(vertebrateAnimalsDict, activeConfiguration)
print(activeConfiguration)

#some other tasks inbetween
...
activeConfiguration = getNextConfig(vertebrateAnimalsDict, activeConfiguration)
print(activeConfiguration)            

My CODE :

#!/usr/bin/env python
   
def getNextConfig(data, activeConfiguration):
    key_count=len([ele for ele in data if isinstance(ele,dict)])
    val_index=-1   
    for dic in data:   
        for k,v in dic.items(): 
            if k==activeConfiguration[0]:                
                key_index=next((i for i,d in enumerate(data) if k in d), None)
                v=data[key_index][k]
                v = v.split(',')                
                val_index=v.index(activeConfiguration[1])
                if val_index != (len(v)-1):                    
                    return [k,v[val_index 1]]
                elif key_index==(key_count-1) and val_index == (len(v)-1):
                    return []
                else:
                    val_index=0
                    key_index=key_index 1
                    break
                
            if val_index==0:
                v=data[key_index][k]
                v = v.split(',')
                return [k,v[val_index]] 
            else:
                continue 

                       

My Expected Output result :-

Reptiles : Snakes
Reptiles : lizards
Reptiles : crocodiles
Reptiles : alligators
Reptiles : turtles
Mammals  : dogs
Mammals  : cats
and so on ...

CodePudding user response:

It would be simple to do the following:

Create one dictionary from the list of dictionaries:

dict1 = {k: v.split(", ") for x in vertebrateAnimalsDict for k, v in x.items()}

EDIT:

Convert this to a series and explode (so each item in the list of values is on a different row):

pairs = pd.Series(dict1).explode()

This small function:

def getNextConfig(pair):
    # get list of bools for whether item matches, and "shift"
    x = pairs[[False]   list(pairs == pair[1])[:-1]]
    # print the pair, for example
    print([x.index.item(), x.item()])
    # return the pair
    return [x.index.item(), x.item()]

Then running the code from the start:

pair = ["Reptiles", "Snakes"]
pair = getNextConfig(pair) # repeat this line to the end (and error on the very last, where it cannot continue)

And the old answer's loop, just in case you decide that you will loop through every combination or want to do this in the future:

for k, v in dict1.items():
    for idx in range(len(v)):
        print([k, v[idx]])
        
        # the other code here...

CodePudding user response:

If I understand your question correctly, you could just use a generator to iterate the values:

def getNextConfig(data):
    for dic in data:
        for key, value in dic.items():
            values = value.split(', ')
            for v in values:
                yield key, v

You might then loop over it like this:

configs = getNextConfig(vertebrateAnimalsDict)
for k, v in configs:
    print(f'{k} : {v}')

Output (for your sample data):

Reptiles : Snakes
Reptiles : lizards
Reptiles : crocodiles
Reptiles : alligators
Reptiles : turtles
Mammals : dogs
Mammals : cats
Mammals : horses
Mammals : duckbill platypuses
Mammals : kangaroos
Mammals : dolphins
Mammals : whales
Minibeasts : Insects
Minibeasts : spiders
Minibeasts : crustaceans

Or to match your code style in the question, we use next to fetch the next value from the generator:

configs = getNextConfig(vertebrateAnimalsDict)
activeConfiguration = next(configs, None)
if activeConfiguration is not None:
    # do something with it

Note we supply a default value to next to avoid a StopIteration error.

  • Related