Python matching keys in list of dicitonaries - python-3.x

I have the following list of dictionaries, with sub dictionaries data:
data2 = [
{"dep": None},
{"dep": {
"eid": "b3ca7ddc-0d0b-4932-816b-e74040a770ec",
"nid": "fae15b05-e869-4403-ae80-6e8892a9dbde",
}
},
{"dep": None},
{"dep": {
"eid": "c3bcaef7-e3b0-40b6-8ad6-cbdb35cd18ed",
"nid": "6a79c93f-286c-4133-b620-66d35389480f",
}
},
]
And I have a match key:
match_key = "b3ca7ddc-0d0b-4932-816b-e74040a770ec"
And I want to see if any sub dictionaries of each "dep" key in data2 have an eid that matches my match_key. I'm trying the following, but I get a TypeError: string indices must be integers - where am I going wrong?
My Code
matches = [
d["eid"]
for item in data2
if item["dep"]
for d in item["dep"]
if d["eid"] == match_key
]
So matches should return:
["b3ca7ddc-0d0b-4932-816b-e74040a770ec"]
Meaning it found this id in data2.

When you iterate over a dictionary, each iteration gives you a key from the dictionary.
So d["eid"] is actually "eid"["eid"], which is an invalid expression. That's why Python raises the following exception:
TypeError: string indices must be integers
Also, the expression d["eid"] assumes that every d contains the eid key. If it doesn't, Python will raise a KeyError.
If you don't know for sure that "eid" is a valid key in the dictionary, prefer using the .get method instead.
matches = [
v
for item in data2
if item.get("dep") # Is there a key called dep, and it has a non-falsy value in it
for k, v in item["dep"].items() # Iterate over the dictionary items
if k == "eid" and v == match_key
]
You can do even better by directly accessing the value of eid key:
matches = [
d["dep"]["eid"]
for d in data2
if d.get("dep") and d["dep"].get("eid") == match_key
]

Related

assign value to a variable in a list in Python

I have a list of lists in the format
list = [["text1",index_value1],["text2",index_value2],["text3",index_value3]]
In a for loop I want to assign values to index_value1, index_value2, ...
If I do
list[0][1] = 5
I would replace index_value1 in the list with 5 instead assigning the value 5 to index_value1.
How can I assign the value to the variable instead of replacing the variable in the list.
I could change the list to
list = [["text1","index_value1"],["text2","index_value2"],["text3","index_value3"]]
If this simplifies the solution.
Thanks for any help
This is a workaround using Python dictionary, as you cannot assign a value to a variable in a list without declaring it first.
dict = {
0: {"id": "text1", "index_value1": None},
1: {"id": "text2", "index_value2": None},
2: {"id": "text3", "index_value3": None}
}
To assign a value:
dict[0]["index_value1"] = 5
How do you want a assign a variable like a array or an dictionary ? without that it replace the indexvalue variable with a value you provided.
index_value1 = None
index_value2 = None
index_value3 = None
list1 = [["text1", index_value1], ["text2", index_value2], ["text3", index_value3]]
for val in list1:
val[1] = 5
print(list1)

Groovy: Adding elements to a collection

I've the following collection
def a = [
b:[
[
c: "x",
d: ["y","z"]
]
],
b1:[
[
c: "x1",
d: ["y1","z1"]
]
]
]
I want to add a new element "w" to d:["y", "z"] to have this d:["y", "z", "w"]
I've tried a.put(d:"w"), a.add(d:"w") but getting exception
groovy.lang.MissingMethodException: No signature of method: java.util.LinkedHashMap.put() is applicable for argument types: (String) values: [w]
You have take into account all your nesting here. You have a map to
list to map. The main problem is the list now, since your example makes
it not clear, how many list items b could hold. So the solution for
your exact example is:
a.b[0].d << "w"

Removing specific value from list of key value pair from Dictionary in Python

Below is the dictionary set I have
dict = {'city':[('hyderabad','pune','chennai'),'state':[('Telangana','mumbai','tamilnadu')]}
I'm trying to remove the first two strings from the list in key value pair from this dictionary, so it will look the same as below
dict = {'city':[('chennai'),'state':[('tamilnadu')]}
I have tried:
for v in dict.values():
del v[0:1]
but this deletes the whole list instead of first two indexes, need help in deleting only the first two indexes of each value list in key value pair
You can use list slicing:
dct = {
"city": [("hyderabad", "pune", "chennai")],
"state": [("Telangana", "mumbai", "tamilnadu")],
}
dct = {k: [l[2:] for l in v] for k, v in dct.items()}
print(dct)
Prints:
{
'city': [('chennai',)],
'state': [('tamilnadu',)]
}
Try this:
dictionary = {
'city':[('hyderabad','pune','chennai')],
'state':[('Telangana','mumbai','tamilnadu')]
}
dict_new = {}
for key, value in dictionary.items():
dict_new[key] = [value[0][2:],]
print(dict_new)
Or, if you prefer to use comprehension notation...
dict_new = {key: [value[0][2:],] for key, value in dictionary.items()}
print(dict_new)
Output:
{
'city': [('chennai',)],
'state': [('tamilnadu',)]
}
Btw.. Try don't use reserved words like dict, tuple, str, etc. like variables names

Is there a simpler way to extract the last value of a dictionary?

So I was tasked to make a function using python, that returns how many values there is in a dictionary that ONLY contains lists. An example of such a dictionary would be:
animals = { 'a': ['alpaca','ardvark'], 'b': ['baboon'], 'c': ['coati']}
The values inside the list also count towards the total values returned from the function, which means that it has to return 4. This is the function I made:
def how_many(aDict):
'''
aDict: A dictionary, where all the values are lists.
returns: int, how many values are in the dictionary.
'''
numValues = 0;
while aDict != {}:
tupKeyValue = aDict.popitem();
List = tupKeyValue[1];
numValues += len(List);
return numValues;
So I was wondering if there was a way to pop the last value of a dictionary without popitem() which extracts the key-value pair. Just trying to make it as simple as possible.
Since you are not using the dictionaries keys maybe you could just use values() along with sum():
def how_many(d):
return sum(len(v) for v in d.values())
animals = {'a': ['alpaca', 'ardvark'], 'b': ['baboon'], 'c': ['coati']}
print(how_many(animals))
Output:
4

How to get keys from nested dictionary of arbitrary length in Python

I have a dictionary object in python. Let's call it as dict. This object could contain another dictionary which may in turn contain another dictionary and so on.
dict = { 'k': v, 'k1': v1, 'dict2':{'k3': v3, 'k4':v4} , 'dict3':{'k5':v5, dict4:{'k6':v6}}}
This is just an example. Length of outermost dictionary could be anything. I want to extract keys from such dictionary object in following two ways :
get list of only keys.
[k,k1,k2,k3,k4,k5,k6]
get list of keys and its parent associated dictionary so something like this :
outer_dict_keys = [k ,dict2, dict3]
dict2_keys = [k3,k4]
dict3_keys = [k5, dict4]
dict4_keys = [k6]
Outermost dictionary dict length is always changing so I can not hard code anything.
What is best way to achieve above result ?
Use a mix of iteration and tail recursion. After quoting undefined names, making spacing uniform, and removing 'k2' from the first result, I came up with the code below. (Written and tested for 3.4, it should run on any 3.x and might on 2.7.) A key thing to remember is that the iteration order of dicts is essentially random, and varies with each run. Recursion as done here visit sub-dicts in depth-first rather than breadth-first order. For dict0, both are the same, But if dict4 were nested in dict2 rather than dict3, they would not be.
dict0 = {'k0': 0, 'k1': 1, 'dict2':{'k3': 3, 'k4': 4},
'dict3':{'k5': 5, 'dict4':{'k6': 6}}}
def keys(dic, klist=[]):
subdics = []
for key in sorted(dic):
val = dic[key]
if isinstance(val, dict):
subdics.append(val)
else:
klist.append(key)
for subdict in subdics:
keys(subdict, klist)
return klist
result = keys(dict0)
print(result, '\n', result == ['k0','k1','k3','k4','k5','k6'])
def keylines(dic, name='outer_dict', lines=[]):
vals = []
subdics = []
for key in sorted(dic):
val = dic[key]
if isinstance(val, dict):
subdics.append((key,val))
else:
vals.append(key)
vals.extend(pair[0] for pair in subdics)
lines.append('{}_keys = {}'.format(name, vals))
for subdict in subdics:
keylines(subdict[1], subdict[0], lines)
return lines
result = keylines(dict0)
for line in result:
print(line,)
print()
expect = [
"outer_dict_keys = ['k0', 'k1', 'dict2', 'dict3']",
"dict2_keys = ['k3', 'k4']",
"dict3_keys = ['k5', 'dict4']",
"dict4_keys = ['k6']"]
for actual, want in zip(result, expect):
if actual != want:
print(want)
for i, (c1, c2) in enumerate(zip(actual, want)):
if c1 != c2:
print(i, c1, c2)

Resources