I have output from python networkX code:
flow_value, flow_dict = nx.maximum_flow(T, 'O', 'T')
print(flow_dict)
#Output as followesenter
#{'O': {'A': 4, 'B': 6, 'C': 4}, 'A': {'B': 1, 'D': 3}, 'B': {'C': 0, 'E': 3,'D': 4}, 'C': {'E': 4}, 'E': {'D': 1, 'T': 6}, 'D': {'T': 8}, 'T': {}}
I want to extract all the data in the form looks like:
#('O','A',4),('O','B','6'),('O','C','4'),('A','B',1),......,('D','T',8)
Any ways can I traverse thru the nested dict and get the data I need?
I tried this and it works. Some type checking to only capture strings
def retrieve_all_strings_from_dict(nested_dict, keys_to_ignore = None):
values = []
if not keys_to_ignore:
keys_to_ignore = []
else: keys_to_ignore = to_list(keys_to_ignore)
if not isinstance(nested_dict,dict):
return values
dict_stack = []
dict_stack.append(nested_dict)
for dict_var in dict_stack:
data_list = [v for k,v in dict_var.items() if all([isinstance(v,str), k not in keys_to_ignore]) ]
additional_dicts = [v for k,v in dict_var.items() if isinstance(v,dict)]
for x in additional_dicts:
dict_stack.append(x)
for w in data_list:
values.append(w)
return values
Related
I have 2 array of objects:
a = [{'a': 1, 'b': 2}, {'c': 3, 'd': 4}, {'e': 5, 'f': 6}]
b = [{'a': 1, 'b': 2}, {'g': 3, 'h': 4}, {'f': 6, 'e': 5}]
Output:
a - b = [{'c': 3, 'd': 4}] ("-" symbol is only for representation, showing difference. Not mathematical minus.)
b - a = [{'g': 3, 'h': 4}]
In every array, the order of key may be different. I can try following and check for that:
for i in range(len(a)):
current_val = a[i]
for x, y in current_val.items:
//search x keyword in array b and compare it with b
but this approach doesn't feel right. Is there simpler way to do this or any utility library which can do this similar to fnc or pydash?
You can use lambda:
g = lambda a,b : [x for x in a if x not in b]
g(a,b) # a-b
[{'c': 3, 'd': 4}]
g(b,a) # b-a
[{'g': 3, 'h': 4}]
Just test if all elements are in the other array
a = [{'a': 1, 'b': 2}, {'c': 3, 'd': 4}, {'e': 5, 'f': 6}]
b = [{'a': 1, 'b': 2}, {'g': 3, 'h': 4}, {'f': 6, 'e': 5}]
def find_diff(array_a, array_b):
diff = []
for e in array_a:
if e not in array_b:
diff.append(e)
return diff
print(find_diff(a, b))
print(find_diff(b, a))
the same with list comprehension
def find_diff(array_a, array_b):
return [e for e in array_a if e not in array_b]
here is the code for subtracting list of dictionaries
a = [{'a': 1, 'b': 2}, {'c': 3, 'd': 4}, {'e': 6, 'f': 6}]
b = [{'a': 1, 'b': 2}, {'g': 3, 'h': 4}, {'f': 6, 'e': 6}]
a_b = []
b_a = []
for element in a:
if element not in b:
a_b.append( element )
for element in b:
if element not in a:
b_a.append( element )
print("a-b =",a_b)
print("b-a =",b_a)
I am trying to develop a code and half of it is done, I am grouping my diction. I want to create a function to go back to the a_dict from b_dict
I want to print it as this;
Expected output;
a_dict: {'A': 1, 'B': 2, 'C': 3, 'D': 1, 'E': 2, 'F': 3} # Original Diction
Grouped dict: {1: ['A', 'D'], 2: ['B', 'E'], 3: ['C', 'F']} # Grouped Diction
Expected dict: {'A': 1, 'D': 1, 'B': 2, 'E': 2, 'C': 3, 'F': 3} # Expected second output with go_back function. Current output can not do this
Code:
a_dict = {'A': 1, 'B': 2, 'C': 3, 'D': 1, 'E': 2, 'F': 3}
print('a_dict: ', a_dict)
def fun_dict(a_dict):
b_dict = {}
for i, v in a_dict.items():
b_dict[v] = [i] if v not in b_dict.keys() else b_dict[v] + [i]
return b_dict
def go_back(b_dict):
#
# Need a function to convert b_dict to c_dict to go back as the expected output
#
b_dict = fun_dict(a_dict)
print('Grouped dict: ', b_dict)
c_dict = fun_dict(b_dict)
print('Went to the original dict: ', c_dict)
The go_back you want could be like this:
def go_back(b_dict):
r = {}
for k, vv in b_dict.items():
for v in vv:
r[v] = k
return r
Result:
Went to the original dict: {'A': 1, 'D': 1, 'B': 2, 'E': 2, 'C': 3, 'F': 3}
Here is a proposal:
def go_back(b_dict):
return {e: k for k, v in b_dict.items() for e in v}
k = 2
source = 'aaabaaacaaadaaabaaabaaac'
dictonary = {}
for x in range(len(source)):
if source[x:x+k] in dictonary.keys() and source[x+k] == dictonary[source[x:x+k][x+k]]:
dictonary[source[x:x+k][x+k]] += 1
elif source[x:x+k] in dictonary.keys():
dictonary[source[x:x+k]].update({source[x+k] : 1})
else:
dictonary[source[x:x+k]] = {source[x+k] : 1}
End goal is trying to create a nested dictionary that looks like:
{'aa': {'a': 6, 'b': 3, 'c': 2, 'd': 1}, 'ab': {'a': 3}, 'ba': {'a': 3},
'ac': {'a': 1, '': 1}, 'ca': {'a': 1}, 'ad': {'a': 1}, 'da': {'a': 1}}
where if a the same character comes after the n-gram its added to the second dictionary value
Ex: 'aaa' would add 1 to the second dictionary value of 'aa' 'a' + 1
Most of the loop works properly just having trouble with incrementing the second dictionary values, I thought what I had would work but having trouble referencing that value, checking if its equal and then adding 1 if it is.
Suggested solutions are helpful but if someone could explain why Im getting a index error that would be much appreciated.
IndexError: string index out of range
The simplest and easiest solution that comes to my mind would be to simply loop through all n-grams and count on the way.
result = {}
for i in range(len(source)-k):
ngram = source[i:i+k]
if ngram not in r:
r[ngram] = {}
after = source[i+k]
if after not in r[ngram]
r[ngram][after] = 0
r[ngram][after] += 1
print(result)
Go through the string in trigraphs and count the digraphs x+y and following letters z:
count = {}
for x,y,z in zip(source, source[1:], source[2:]):
if x + y not in count: count[x + y] = {}
if z not in count[x + y]: count[x + y][z] = 0
count[x + y][z] += 1
count
#{'aa': {'a': 6, 'b': 3, 'c': 2, 'd': 1}, 'ab': {'a': 3},
# 'ba': {'a': 3}, 'ac': {'a': 1}, 'ca': {'a': 1},
# 'ad': {'a': 1}, 'da': {'a': 1}}
Note: This solution works only for k=2.
I am a beginner in python trying to create a function that filters through my nested dictionary through by asking multiple values in a dictionary like
filtered_options = {'a': 5, 'b': "Cloth'}
For my dictionary
my_dict = {1.0:{'a': 1, 'b': "Food', 'c': 500, 'd': 'Yams'},
2.0:{'a': 5, 'v': "Cloth', 'c': 210, 'd': 'Linen'}}
If I input my dictionary in the filter function with such options I should get something that looks like
filtered_dict(my_dict, filtered_options = {'a': 5, 'b': "Cloth'})
which outputs the 2nd key and other keys with the same filtered options in my dictionary.
This should do what you want.
def dict_matches(d, filters):
return all(k in d and d[k] == v for k, v in filters.items())
def filter_dict(d, filters=None):
filters = filters or {}
return {k: v for k, v in d.items() if dict_matches(v, filters)}
Here's what happens when you test it:
>>> filters = {'a': 5, 'b': 'Cloth'}
>>> my_dict = {
... 1.0: {'a': 1, 'b': 'Food', 'c': 500, 'd': 'Yams'},
... 2.0: {'a': 5, 'b': 'Cloth', 'c': 210, 'd': 'Linen'}
... }
>>> filter_dict(my_dict, filters)
{2.0: {'b': 'Cloth', 'a': 5, 'd': 'Linen', 'c': 210}}
You can do this :
import operator
from functools import reduce
def multi_level_indexing(nested_dict, key_list):
"""Multi level index a nested dictionary, nested_dict through a list of keys in dictionaries, key_list
"""
return reduce(operator.getitem, key_list, nested_dict)
def filtered_dict(my_dict, filtered_options):
return {k : v for k, v in my_dict.items() if all(multi_level_indexing(my_dict, [k,f_k]) == f_v for f_k, f_v in filtered_options.items())}
So that:
my_dict = {1.0:{'a': 1, 'b': 'Food', 'c': 500, 'd': 'Yams'},
2.0:{'a': 5, 'b': 'Cloth', 'c': 210, 'd': 'Linen'}}
will give you:
print(filtered_dict(my_dict, {'a': 5, 'b': 'Cloth'}))
# prints {2.0: {'a': 5, 'b': 'Cloth', 'c': 210, 'd': 'Linen'}}
I am trying to update values for a dict() key dynamically with a for loop.
def update_dict():
f = []
for i, j in enumerate(list_range):
test_dict.update({'a': i})
j['c'] = test_dict
print(j)
f.append(j)
print(f)
test_dict = dict({'a': 1})
list_range = [{'b': i} for i in range(0, 5)]
update_dict()
Even print(j) gives iterating value (0,1,2,3,4), somehow the last dict is getting overwritten all over the list and giving wrong output (4,4,4,4,4).
Expected Output,
[{'b': 0, 'c': {'a': 0}}, {'b': 1, 'c': {'a': 1}}, {'b': 2, 'c': {'a': 2}}, {'b': 3, 'c': {'a': 3}}, {'b': 4, 'c': {'a': 4}}]
Output obtained,
[{'b': 0, 'c': {'a': 4}}, {'b': 1, 'c': {'a': 4}}, {'b': 2, 'c': {'a': 4}}, {'b': 3, 'c': {'a': 4}}, {'b': 4, 'c': {'a': 4}}]
I need to understand how the dictionaries are getting overwritten and what could be the best solution to avoid this?
Thanks in advance!
P.S. : please avoid suggesting list or dict comprehension method as bare answer as i am aware of them and the only purpose of this question is to understand the wrong behavior of dict().
The reason of such behaviour is that all references in list points to the same dict. Line j['c'] = test_dict doesn't create copy of dictionary, but just make j['c'] refer to test_dict. To get expected result you need change this line to:
j['c'] = test_dict.copy(). It will make deep copy of test_dict and assign it to j['c'].
You try to add values to same dictionary every time in the loop and as loop progresses, you keep replacing the values.
You need to define dictionary in every iteration to create separate references of the dictionary:
def update_dict():
f = []
for i, j in enumerate(list_range):
test_dict = {'a': i}
j['c'] = test_dict
f.append(j)
print(f)
list_range = [{'b': i} for i in range(0, 5)]
update_dict()
# [{'b': 0, 'c': {'a': 0}},
# {'b': 1, 'c': {'a': 1}},
# {'b': 2, 'c': {'a': 2}},
# {'b': 3, 'c': {'a': 3}},
# {'b': 4, 'c': {'a': 4}}]
A simpler solution could be to iterate through list_range and create c using the values from b
lista = [{'b': i } for i in range(0, 5)]
for i in lista:
i['c'] = {'a': i['b']}
# [{'b': 0, 'c': {'a': 0}}, {'b': 1, 'c': {'a': 1}}, {'b': 2, 'c': {'a': 2}}, {'b': 3, 'c': {'a': 3}}, {'b': 4, 'c': {'a': 4}}]
def update_dict():
f = []
for i, j in enumerate(list_range):
j['c'] = {'a': i}
print(j)
f.append(j)
return f
list_range = [{'b': i} for i in range(0, 5)]
print(update_dict())
#output
{'b': 0, 'c': {'a': 0}}
{'b': 1, 'c': {'a': 1}}
{'b': 2, 'c': {'a': 2}}
{'b': 3, 'c': {'a': 3}}
{'b': 4, 'c': {'a': 4}}