Appending parameters from a list in a for loop - python

I have a list with several data, ['a','b','c'...]
The goal here is to read all the items in the list and access to a json file to retrieve that information.
The json i have is as follows
{
"a": {
"b": {
"c": { .... }
}
} }
So, the final sentence to execute is
code.get(list[0]).get(list[1]).get(list[2]...get(list[n]
Is there any way i can do a for loop based on the length of the list to do this?
Something like, for any item in the list, append a ..get(list[i]) to my sentence
Thanks

Just iterate over the key list and go down into the code dict:
keys = ['a','b','c']
current_level = code # Top level
for key in keys:
current_level = current_level.get(key) # Descent next level
print current_level # Value of the 'c' dict

Related

How do I create a list inside python dictionary having key and key variable?

I have an empty dictionary. I add key and key variable to that dictionary. How do I create an empty list having key and key variable?
result = {}
result['key'] = 20
print(result)= {'key': 20}
result['key'] = []
result2 = {}
result['key'].append(result2)
Expected result : {'key':20 : [{'7219': '0.49954929481682875'}, {'1416': '0.48741579334133667'}
But it comes like,
{'key': [{'7219': '0.49954929481682875'}, {'1416': '0.48741579334133667'}]
Looks like you need.
result = {}
result['key'] = {20: []}
print(result) # --> {'key': {20: []}}
result2 = {}
result['key'][20].append(result2)
print(result)
As far as I understand your question, you do not necessarily want to save the value "20" with the key "key", but rather use "20" as the key. In order to achieve that, your code should look like the following (careful, this basically spells out every step):
# save an empty list using the key int(20)
# define the key and an empty dictionary
my_key = 20
result = {}
# use the key variable as key for the dictionary and create an empty list there
result[my_key] = []
# now add the other result dictionary to this list
result2 = {
#... some entries
}
result[my_key].append(result2)
# ... some more code
This finally results in a dictionary in this form:
{20 : [{'7219': '0.49954929481682875'}, {'1416': '0.48741579334133667'}]}
However, this is only my interpretation of your issue. If I got something wrong, just ping me up.

Python Nested dictionary compare values internally

I am trying to process a dictionary with keys and each key having a list of values and create a nested dictionary from it. And also compare the values for equality in the list for each key and generate a new dictionary with the list of equal and unequal values.
I was able to loop through the list of values for each key and process them to get a new variable with which I wanted to create the new nested dictionary. But currently a null exception is thrown at the first key value.
dict1 = {a:[d,e,f], b:[p,q,r]}
dict2 = {d:100, e:100, f:100, p:100, q:100, r:100}
dict3 = {d:text1, e: text2, f: text3}
for i in dict1.keys():
for x in dict1[i]:
if dict2[x] == 100:
string = re.findall(r'sometext in text',dict3[x])[0]
ver = re.search('(?is)<i>(.+?)</i>', match_string).group(1)
d[i][x] = ver
Expected result:
d = { a:{d:ver1, e:ver2, f:ver3}, b:{p:ver4, q:ver5, r:ver6 }
After this looping through each nested value, each value needs to be compared with its peers value and arranged in a new dictionary with the keys of the values matching. Something as below:
if d's ver1 = e's ver2 =! f's ver3
dict4 = {a: { equal:[d,e], unequal: [f]}
I don't know where dict3 comes into play with your desired output but this will get the desired output:
dict1 = {'a':['d','e','f'], 'b':['p','q','r']}
dict2 = {'d':100, 'e':100, 'f':100, 'p':100, 'q':100, 'r':100}
result = {key1: {key2: dict2[key2] for key2 in val1} for key1, val1 in dict1.items()}
print(result)
Output:
{
"a": {
"d": 100,
"e": 100,
"f": 100
},
"b": {
"p": 100,
"q": 100,
"r": 100
}
}

python create list of dictionaries without reference

I have a requirement in which I need create dictionary objects with duplicate keys embedded into a list object, something like this:
[{ "key": "ABC" },{ "key": "EFG" } ]
I decided to have a top level list initialized to empty like outer_list=[] and a placeholder dictionary object like dict_obj= {}. Next I keep adding elements to my list using the following steps:
assign { "key": "ABC" } to dict_obj using dict_obj["key"]="ABC"
Add this object to the list using outer_list.append(dict_obj)
Flush/pop the key/items in dictionary object using dict_obj.clear()
Repeat steps 1 to 3 based on the number of key/item combinations in my data
Issue: the outer_list object maintains a reference to the original dict_obj and if the dict_obj is flushed or a new key/item is added it changes accordingly. So finally, I end up with this [{ "key": "EFG" },{ "key": "EFG" } ] instead of [{ "key": "ABC" },{ "key": "EFG" } ]
Please guide me with some workarounds if possible.
I think there are two ways to avoid the duplicate references.
The first is to append a copy of the dictionary, instead of a reference to it. dict instances have a copy method, so this is easy. Just change your current append call to:
outer_list.append(dict_obj.copy())`
The other option is to not always use the same dict_obj object, but rather create a separate dictionary object for each entry. In this version, you'd replace your call to dict_obj.clear() with:
dict_obj = {}
For the second approach, you might choose to reorder things rather than doing a straight one-line replacement. You could move the setup code to the start of the loop and get rid of the reset logic at the end of the loop.
That is, change code that looks like this:
outer_list = []
dict_obj = {}
for foo in whatever:
# add stuff to dict_obj
outer_list.append(dict_obj)
dict_obj.clear()
To:
outer_list = []
for foo in whatever:
dict_obj = {}
# add stuff to dict_obj
outer_list.append(dict_obj)
If the logic for creating the inner dictionaries is simple enough to compute, you might even turn the whole thing into a list comprehension:
outer_list = [{"key": value, "key2": value2} for value, value2 in some_sequence]
The following should be self-explanatory:
# object reuse
d = {}
l = []
d['key'] = 'ABC'
l.append(d)
d.clear()
print(l) # [{}] : cleared!
d['key'] = 'EFG'
l.append(d)
print(l) # [{'key': 'EFG'}, {'key': 'EFG'}]
# explicit creation of new objects
d = {}
l = []
d['key'] = 'ABC'
l.append(d)
print(l)
d = {}
d['key'] = 'EFG'
l.append(d)
print(l)

How to remove dictionary's keys and values based on another dictionary?

I wish to remove keys and values in one JSON dictionary based on another JSON dictionary's keys and values. In a sense I am looking perform a "subtraction". Let's say I have JSON dictionaries a and b:
a = {
"my_app":
{
"environment_variables":
{
"SOME_ENV_VAR":
[
"/tmp",
"tmp2"
]
},
"variables":
{ "my_var": "1",
"my_other_var": "2"
}
}
}
b = {
"my_app":
{
"environment_variables":
{
"SOME_ENV_VAR":
[
"/tmp"
]
},
"variables":
{ "my_var": "1" }
}
}
Imagine you could do a-b=c where c looks like this:
c = {
"my_app":
{
"environment_variables":
{
"SOME_ENV_VAR":
[
"/tmp2"
]
},
"variables":
{ "my_other_var": "2" }
}
}
How can this be done?
You can loop through your dictionary using for key in dictionary: and you can delete keys using del dictionary[key], I think that's all you need. See the documentation for dictionaries: https://docs.python.org/2/tutorial/datastructures.html#dictionaries
The way you can do it is to:
Create copy of a -> c;
Iterate over every key, value pair inside b;
Check if for same top keys you have same inner keys and values and delete them from c;
Remove keys with empty values.
You should modify code, if your case will be somehow different (no dict(dict), etc).
print(A)
print(B)
C = A.copy()
# INFO: Suppose your max depth is as follows: "A = dict(key:dict(), ...)"
for k0, v0 in B.items():
# Look for similiar outer keys (check if 'vars' or 'env_vars' in A)
if k0 in C:
# Look for similiar inner (keys, values)
for k1, v1 in v0.items():
# If we have e.g. 'my_var' in B and in C and values are the same
if k1 in C[k0] and v1 == C[k0][k1]:
del C[k0][k1]
# Remove empty 'vars', 'env_vars'
if not C[k0]:
del C[k0]
print(C)
{'environment_variables': {'SOME_ENV_VAR': ['/tmp']},
'variables': {'my_var': '2', 'someones_var': '1'}}
{'environment_variables': {'SOME_ENV_VAR': ['/tmp']},
'variables': {'my_var': '2'}}
{'variables': {'someones_var': '1'}}
The following does what you need:
def subtract(a, b):
result = {}
for key, value in a.items():
if key not in b or b[key] != value:
if not isinstance(value, dict):
if isinstance(value, list):
result[key] = [item for item in value if item not in b[key]]
else:
result[key] = value
continue
inner_dict = subtract(value, b[key])
if len(inner_dict) > 0:
result[key] = inner_dict
return result
It checks if both key and value are present. It could del items, but I think is much better to return a new dict with the desired data instead of modifying the original.
c = subtract(a, b)
UPDATE
I have just updated for the latest version of the data provided by in the question. Now it 'subtract' list values as well.
UPDATE 2
Working example: ipython notebook

How do I find an item in an array of dictionaries?

Suppose I have this:
list = [ { 'p1':'v1' } ,{ 'p2':'v2' } ,{ 'p3':'v3' } ]
I need to find p2 and get its value.
You can try the following ... That will return all the values equivilant to the givenKey in all dictionaries.
ans = [d[key] for d in list if d.has_key(key)]
If this is what your actual code looks like (each key is unique), you should just use one dictionary:
things = { 'p1':'v1', 'p2':'v2', 'p3':'v3' }
do_something(things['p2'])
You can convert a list of dictionaries to one dictionary by merging them with update (but this will overwrite duplicate keys):
dict = {}
for item in list:
dict.update(item)
do_something(dict['p2'])
If that's not possible, you'll need to just loop through them:
for item in list:
if 'p2' in item:
do_something(item['p2'])
If you expect multiple results, you can also build up a list:
p2s = []
for item in list:
if 'p2' in item:
p2s.append(item['p2'])
Also, I wouldn't recommend actually naming any variables dict or list, since that will cause problems with the built-in dict() and list() functions.
These shouldn't be stored in a list to begin with, they should be stored in a dictionary. Since they're stored in a list, though, you can either search them as they are:
lst = [ { 'p1':'v1' } ,{ 'p2':'v2' } ,{ 'p3':'v3' } ]
p2 = next(d["p2"] for d in lst if "p2" in d)
Or turn them into a dictionary:
dct = {}
any(dct.update(d) for d in lst)
p2 = dct["p2"]
You can also use this one-liner:
filter(lambda x: 'p2' in x, list)[0]['p2']
if you have more than one 'p2', this will pick out the first; if you have none, it will raise IndexError.
for d in list:
if d.has_key("p2"):
return d['p2']
If it's a oneoff lookup, you can do something like this
>>> [i['p2'] for i in my_list if 'p2' in i]
['v2']
If you need to look up multiple keys, you should consider converting the list to something that can do key lookups in constant time (such as a dict)
>>> my_list = [ { 'p1':'v1' } ,{ 'p2':'v2' } ,{ 'p3':'v3' } ]
>>> my_dict = dict(i.popitem() for i in my_list)
>>> my_dict['p2']
'v2'
Start by flattening the list of dictionaries out to a dictionary, then you can index it by key and get the value:
{k:v for x in list for k,v in x.iteritems()}['p2']

Categories