Add a value to an array contained in a dictionary - python-3.x

Please how to add a new element to an array which is a value of a dictionary?
When I try to add the element like this:
res[key].append(newelement)
it just erases the previous value.
My complete code looks like
data = [{"signal_name": "X", "signal_value": "valueX1"},
{"signal_name": "Y", "signal_value": "valueY1"},
{"signal_name": "Z", "signal_value": "valueZ1"},
{"signal_name": "X", "signal_value": "valueX2"}]
res = {}
for i in data:
for k, v in i.items():
if k == "signal_name":
res[v] = []
temp = v
if k == "signal_value":
res[temp].append(v)
my output looks like this
Reading from input
{'X': ['valueX1']}
{'X': ['valueX1'], 'Y': ['valueY1']}
{'X': ['valueX1'], 'Y': ['valueY1'], 'Z': ['valueZ1']}
{'X': ['valueX2'], 'Y': ['valueY1'], 'Z': ['valueZ1']}
Done reading
so the X value is updated rather than contains the ['valueX1', 'valueX2']

res[temp].append(v) works well. In res[v] = [] line, you are assigning an empty list when you encounter X second time and ever time you encounter again.
I recommend you to use dictionary get() function.
res = {}
for d in data:
key = d["signal_name"]
value = d["signal_value"]
l = res.get(key, []) # Return [] if key is not in the dictonary
l.append(value)
res[key] = l
print(res)
Output:
{'X': ['valueX1', 'valueX2'], 'Y': ['valueY1'], 'Z': ['valueZ1']}

Try the below code, Hope this will help:
data = [{"signal_name": "X", "signal_value": "valueX1"},
{"signal_name": "Y", "signal_value": "valueY1"},
{"signal_name": "Z", "signal_value": "valueZ1"},
{"signal_name": "X", "signal_value": "valueX2"}]
res = {}
for i in data:
temp = None
for k, v in i.items():
if k == "signal_name":
try:
res[v]
except:
res[v]=[] #<-- As everytime you were initializing it, this was the error
temp = v
if k == "signal_value":
print(temp)
print(res[temp])
res[temp].append(v)
Ouput will be :
{'X': ['valueX1', 'valueX2'], 'Y': ['valueY1'], 'Z': ['valueZ1']}

Related

Iterate between List and Dictionary, handle with no found elements

Good evening, I'm sorry if there is already something similar to my question, but I couldn't find an answer.
I'm trying to deal with values ​​that don't exist in an iteration between the items in a list and the keys in a dictionary.
lista = [1, 2, 3, 4, 5]
dicionario = {"1": {"x": 77.25, "y": 116.330078125},
"2": {"x": 88.25, "y": 126.330078125},
"3": {"x": 99.25, "y": 136.330078125}}
novo_dicionario = {}
for item in lista:
for key, value in dicionario.items():
if str(item) == key:
for v in value.items():
if v[0] in list(novo_dicionario.keys()):
novo_dicionario[v[0]].append(v[1])
else:
novo_dicionario[v[0]] = [v[1]]
Resulting in:
{'x': [77.25, 88.25, 99.25], 'y': [116.330078125, 126.330078125, 136.330078125]}
As you can see, "1, 2, 3" exists as a key in the dictionary. But "4 and 5" does not. So in this case, I'd like my result to handle this exception and look like this:
{'x': [77.25, 88.25, 99.25, 0.00, 0.00], 'y': [116.330078125, 126.330078125, 136.330078125, 0.00, 0.00]}
And as the list grew and was not found as a key in the dictionary, "0.00" was added in the respective amount.
This is what I tried:
for item in lista:
for key, value in dicionario.items():
for v in value.items():
if str(item) == key:
if v[0] in list(novo_dicionario.keys()):
novo_dicionario[v[0]].append(v[1])
else:
novo_dicionario[v[0]] = [v[1]]
else:
for v in value.items():
if v[0] in list(novo_dicionario.keys()):
novo_dicionario[v[0]].append(0.00)
else:
novo_dicionario[v[0]] = [0.00]
But this piece of code adds a lot of 0.00 and not only for each item.
You can easily solve it using defaultdict:
import collections
result = collections.defaultdict(list)
for key in lista:
if str(key) in dicionario:
adict = dicionario[str(key)]
result['x'].append(adict['x'])
result['y'].append(adict['y'])
else:
result['x'].append(0.00)
result['y'].append(0.00)
print(dict(result))
Output:
{'x': [77.25, 88.25, 99.25, 0.0, 0.0], 'y': [116.330078125, 126.330078125, 136.330078125, 0.0, 0.0]}
First, let's get the keys present in each sub-dictionary using set intersection.
from functools import reduce
keys = reduce(set.intersection, (set(d.keys()) for d in dicionario.values()))
# => {'y', 'x'}
Now we can write a dictionary comprehension that makes use of dict.get to provide default fallbacks for a missing key scenario.
{k: [dicionario.get(str(i), {}).get(k, 0.00) for i in lista] for k in keys}
# => {'y': [116.330078125, 126.330078125, 136.330078125, 0.0, 0.0], 'x': [77.25, 88.25, 99.25, 0.0, 0.0]}

How to store key, value pair in dictionary from file?

I have an input.txt file like below format.
A = Xyz
B
Value:274:53:3
C = 1190
E
WQQQW
Value:554
A = UrR
B
Value:113:00:1
C = 34
E
WQQQW
Value:982
I'd like to store in a dictionary the data related with A, B and E in order to get:
d = {
'A': ['Xyz', 'UrR'],
'B': ['274:53:3', '113:00:1'],
'E': ['554', '982'],
}
I'm doing like below, not I only storing the key, value pair related with A since the values for A are in the same line.
d = {"A":[],"B":[],"E":[]}
for line in open('input.txt'):
lst_line = line.replace(":", "=", 1).split("=")
if ("A" or "B" or "E") in lst_line[0]:
k = lst_line[0].strip()
v = lst_line[1].replace("\n", "").strip()
d[k].append(v)
>>> d
{'A': ['Xyz', 'UrR'], 'B': [], 'E': []}
I'm stuck in how to store the values for B that is one line below after Value: and for E that is 2 lines below after Value:.
Every key seems to have a very specific logic which can be divided into independent if conditions. Below code reads value for respective key based on the condition mentioned in question.
d = {"A": [], "B": [], "E": []}
with open("input.txt") as file:
while True:
line = file.readline() # read next line
if not line:
break # break on end of file
lst_line = line.replace(":", "=", 1).split("=") # key from line
if "A" in lst_line[0]:
k = lst_line[0].strip()
v = lst_line[1].replace("\n", "").strip()
d[k].append(v)
if "B" in lst_line[0]:
k = lst_line[0].strip()
line = file.readline() # read next line for value i.e. if key is B value is on the next line (one line below)
lst_line = line.replace(":", "=", 1).split("=") # get value for B
v = lst_line[1].replace("\n", "").strip()
d[k].append(v)
if "E" in lst_line[0]:
k = lst_line[0].strip()
file.readline() # skip junk line
line = file.readline() # read next line for value i.e. for E value is two lines below.
lst_line = line.replace(":", "=", 1).split("=") # get value for E
v = lst_line[1].replace("\n", "").strip()
d[k].append(v)
print(d)
Output:
{'A': ['Xyz', 'UrR'], 'B': ['274:53:3', '113:00:1'], 'E': ['554', '982']}
Here is how you can use regex:
import re
with open('file.txt', 'r') as r:
r = r.read()
dct = {'A': re.findall('(?<=A \= ).*?(?= \n)',r),
'B': re.findall('\d\d\d:\d\d:\d',r),
'E': re.findall('(?<=Value:)\d\d\d(?!:)',r)}
print(dct)
Output:
{'A': ['Xyz', 'UrR'],
'B': ['274:53:3', '113:00:1'],
'E': ['554', '982']}

python recursion avoid result as global variable

res_dict = {}
def get_value(co , passed_dict ):
for k, v in passed_dict.items():
if isinstance(v, dict):
get_value(co, v)
else:
res_dict[k] = v
print("from else",res_dict)
return res_dict
def easy():
inner_dict = {
"test1" : {"test1_in" : "abc"},
"test2" : {"test1_in" : "xyz"}
}
dict1 = {}
count = 0
val_from_function= {}
key_list = ['key1','key2']
for key in key_list:
count = count + 1
val_from_function = get_value(count ,inner_dict)
print("before assign" ,dict1 )
dict1[key] = val_from_function
print("after assign" , dict1)
# dict1['key1'] = {'test1' : "abc"}
# dict1['key2'] = {'test1' : "xyz"}
print(dict1)
easy()
receiving output : {'key1': {'test1_in': 'xyz'}, 'key2': {'test1_in': 'xyz'}}
expected o/p : {'key1': {'test1_in': 'abc'}, 'key2': {'test1_in': 'xyz'}}
I understand the value of dict1 is updated with the last value as res_dict declared as global
variable.
I can solve it by appending the inner key value with outer key and then storing in dictionary.
I might solve it using ordered dictionary.
taking keys from list as outer key value (key1, key2 ..,key3000) is unknown.
Looking for suggestions on how to make this code better with expected o/p.
Have 3k key-pair values, same as sample pattern with more nested k,v & storing o/p as cache, so performance is not a very big issue here.
# This modifies passed_dict
def get_value(passed_dict, recur_dict_new={}, isInitial=True):
for k, v in passed_dict.items():
if isInitial:
recur_dict_new = {}
if isinstance(v, dict):
temp = get_value(v, recur_dict_new, isInitial=False)
passed_dict[k]= temp
else:
recur_dict_new[k]=v
return recur_dict_new
def easy():
inner_dict = {
"test1" : {"test1_in" : "abc"},
"test2" : {"test1_in" : "xyz"}
}
key_list = ['key1','key2']
for key in key_list:
get_value(inner_dict)
# dict1['key1'] = {'test1' : "abc"}
# dict1['key2'] = {'test1' : "xyz"}
print(inner_dict)
easy()
Thanks for looking, I have solved with one of the ways as mentioned above,
tested with 15k records with 3 more levels of nested JSON, the performance was okay(4ms)
O/p : {'test1': {'test1_in': 'abc'}, 'test2': {'test1_in': 'xyz'}}

keep certain values in a dictionary values based on list

I have a dictionary d
d = {'1': ['Fisherman', 'fam', '125', '53901', 'funny'],
'2': ['Joi', '521', 'funny','fun', '1245']}
and a list l
l = ['521', 'Fisherman', 'fun','A2ML1', 'A3GALT2','funny']
I want to keep values in d that are not in l. I want my output to be
d_list = {'1': ['fam','125', '53901'],'2': ['Joi', '1245']}
To do so, I tried this
d_list = []
for k, v in d.items():
if v not in l:
d_list.append(v)
But this doesn't give me what I want. What can I do to my code (or new code) to get my desired d_list?
v is a list not a str
try this code:
d1 = {}
for k, v in d.items():
d1[k] = [i for i in v if i not in l]
d1
output:
{'1': ['fam', '125', '53901'], '2': ['Joi', '1245']}
you can doe it like this also
{key:set(values) - set(l) for key, values in d.items()}
or if you want values to be list instead of set
{key:list(set(values) - set(l)) for key, values in d.items()}

creating a dict based on two python dicts

I have two python dicts:
payload = {"key1":{"a":"1"},"key2":{"b":"2","c":"3"}}
and
data = {"1":"John","2":"Jacob"}
I would like my output to be:
{"key1":{"a":"John"},"key2":{"b":"Jacob","c":""}}
Any method that I try correctly prints the values, but does not update the output dictionary.
You can do something like this using dict comprehension :
payload = {"key1":{"a":"1"},"key2":{"b":"2","c":"3"}}
data = {"1":"John","2":"Jacob"}
final = {k: {i:data[j] if j in data.keys() else "" for i, j in payload[k].items()} for k in payload}
print(final)
Output:
{'key2': {'b': 'Jacob', 'c': ''}, 'key1': {'a': 'John'}}
There is no single method for this I am aware of, but you can use:
for k, v in payload.viewitems():
payload[k] = {}
for kv, vv in v.viewitems():
payload[k][kv] = data.get(vv, "")
if you then inspect payload it has the contents you are after:
{'key2': {'c': '', 'b': 'Jacob'}, 'key1': {'a': 'John'}}

Resources