python replace json list values without knowing the keys - python

I have this code snippet:
data = {
"links": [
{"key_name_not_known": "replace_by_first_value_in_list"},
{"key_name_not_known": "replace_by_second_value_in_list"},
]
}
list = ["hello1", "hello2"]
Here I want to replace both values "hello" in data["links"] ["keys"]? without knowing the key value by the two values in the list, in the right order.
A goal output would be:
data = {
"links": [
{"key_name_not_known": "hello1"},
{"key_name_not_known": "hello2"},
]
}
How can I do that ?

for index, obj in enumerate(data['links']):
for key,val in obj.items():
if len(list) > index:
data['links'][index][key] = list[index]

Related

Dynamic length list of objects where each object's key-values are reassigned regardless of which list index is specified, but static list functions

First question here, so go easy on me.
I am attempting to assign a list of objects which represent an accumulator of 1s and 0s at each index location of a large input of binary strings ex: 011011101.
I wanted to read the first row of my input to get the length of the binary string, and then assign a variable that looks like -> "[ {0:0, 1:0} ] * len(n)" for the sake of brevity, I know that all rows will be a length of 12.
My objective: loop over each item in a row, and add 1 to either the 1 or 0 at that index location's object key. -> "arr[i][v] += 1"
i represents both the string index AND the object I want to access in the dynamically sized array
v represents the key(0 or 1) of the object at i location that i want to increment by 1
In this way I can figure out how many 1s or 0s are at each position of a given input.
simplified code:
`
input = ["010101101100", "110001101101"]
arr = [{ 0:0,1:0 }] * len(input[0])
for row in input:
for i, v in enumerate(row):
v = int(v)
arr[i][v] += 1
print(arr)
`
WRONG Result!
However, if I explicitly set the list as such:
input = ["010101101100", "110001101101"]
arr = [
{ 0:0,1:0 },
{ 0:0,1:0 },
{ 0:0,1:0 },
{ 0:0,1:0 },
{ 0:0,1:0 },
{ 0:0,1:0 },
{ 0:0,1:0 },
{ 0:0,1:0 },
{ 0:0,1:0 },
{ 0:0,1:0 },
{ 0:0,1:0 },
{ 0:0,1:0 }
]
for i, v in enumerate(input):
v = int(v)
arr[i][v] += 1
print(arr)
The correct Answer!
What exactly is going on here? Why is the loop that accesses the dynamic list applying the addition to each object and corresponding key-value pair?
I'm sure it is some computer science thing that I'm just not getting.
The only reason this is sort of not making my head explode is that I could see the input, and I could just set the list explicitly, but if the length was unknown it would be an issue
When you use *, Python creates a list where each element references the same object. Thus, modifying one element ends up modifying all of them.
arr = [{0:0, 1:0}] * 12 # this creates a list where every element is the same dictionary
arr = [{0:0, 1:0} for _ in range(12)] # this creates a list containing 12 independent dictionaries

How to find the last matched key by comparing with list and dictionary

A list and dictionary is below
main_list = ["projecttype","emptype","Designation"]
sample = {"query": {
"emptype":["Manager"],"projecttype":["temp"],
"from": [
"0"
],
"q": [
""
],
"size": [
"4"
]
}}
How to find from the main_list which key is last "entered key" in sample dictionary
How to find from the main_list which key is first "entered key" in sample dictionary
In this particular scenario
"projecttype" is my output for last entered key which matches
emptype is my output for first entered key which matches
You can iterate through it and test if the keys are in your main_list. Save every key that is in main_list and after the for loop you will have the last entered key.
main_list = ["projecttype","emptype","Designation"]
sample = {
"query": {
"emptype": ["Manager"],
"projecttype": ["temp"],
"from": ["0"],
"q": [""],
"size": ["4"]
}
}
first = None
last = None
for key, value in sample['query'].items():
if key in main_list:
if first is None:
first = key
last = key
print('First:', first)
print('Last:', last)
You could do this in a cuple of lines and have the order of all the elements that are contained in your main_list as follow:
sample_query_keys = list(sample['query'].keys())
result = {sample_query_keys.index(main_key):main_key for main_key in main_list if main_key in sample_query_keys}
Then you can get the first and last item as follow:
print(result[0], result[len(result)-1])
Keep in mind that this will only work if the dictionary is ordered. That is only possible in Python 3.7 onwards. For previous versions, you would need to use OrderedDict.

Remove duplicate of a dictionary from list

How can i remove duplicate of the key "name"
[
{
'items':[
{
'$oid':'5a192d0590866ecc5c1f1683'
}
],
'image':'image12',
'_id':{
'$oid':'5a106f7490866e25ddf70cef'
},
'name':'Amala',
'store':{
'$oid':'5a0a10ad90866e5abae59470'
}
},
{
'items':[
{
'$oid':'5a192d2890866ecc5c1f1684'
}
],
'image':'fourth shit',
'_id':{
'$oid':'5a106fa190866e25ddf70cf0'
},
'name':'Amala',
'store':{
'$oid':'5a0a10ad90866e5abae59470'
}
}
]
I want to marge together dictionary with the same key "name"
Here is what i have tried
b = []
for q in data:
if len(data) == 0:
b.append(q)
else:
for y in b:
if q['name'] != y['name']:
b.append(q)
but after trying this the b list doesn't return unique dictionary that i wanted
You loop through the assembled list and if you find a dict with a different name, you add the current dict. The logic should be different: only add it if you don't find one with the same name!
That being said, you should maintain a set of seen names. That will make the check more performant:
b, seen = [], set()
for q in data:
if q['name'] not in seen:
b.append(q)
seen.add(q['name'])

using python - grab only particular values from key:value pairs in parsed JSON

I am trying to extract particular data from a JSON file. Here is my code.
jsonurl = http://localhost:8080/test.json
a = urllib2.urlopen(jsonurl).read()
b = json.loads(a)
for x, y in b.iteritems():
print x, y
here is my json
{
"abc": [
"build=1.0.44.0",
"proxy=none"
],
"xyz": [
"proxy=https",
"build=1.0.127.0"
],
"alfa": [
"build=1.0.118.0",
"proxy=none"
],
"beta": [
"proxy=http"
"build=1.0.20.0"
]
}
I am getting all both the key and value from the json but i only need to extract key: value of (build =).
my desired output is
abc:1.0.44.0
xyz:1.0.127.0 ....etc I tried many options but couldn't get desired results.
jsonurl = http://localhost:8080/test.json
a = urllib2.urlopen(jsonurl).read()
b = json.loads(a)
for x, y in b.iteritems():
print x, y
Prints each key/value in the dictionary. Each of your values is actually a list, so to access a list item, you would need to use the proper syntax.
for x, y in b.iteritems():
print x, y, y[0]
Will show your key, value, and value[0].
Now, identify which element of the list contains the build= string:
> my_list = ["proxy=https", "build=1.0.127.0"]
> build_str = [i for i in my_list if 'build=' in i][0]
> build_str
build=1.0.127.0
From there, you can evolve your program to parse the string. To parse a string as you are asking, I usually look for an easy 'split' delimiter. In this case, the = stands out. Split will take a string and create a list with breaks at every delimiter.
> my_str_as_a_list = "build=1.0.20.0".split('=')
> my_str_as_a_list
['build', '1.0.20.0']
> my_str_as_a_list[1]
1.0.20.0
Now, apply this concept to your for loop:
for key, value in b.iteritems():
my_str = [i for i in value if 'build=' in i][0]
v = my_str.split('=')[1]
print '{}:{}'.format(key, v)
I am not sure if you want an output in the form of a dictionary/string/list based on your question, but you should be able to get there easily with the provided answers.
Try as follows:
data = {
"abc": [
"build=1.0.44.0",
"proxy=none"
],
"xyz": [
"build=1.0.127.0",
"proxy=https"
],
"alfa": [
"build=1.0.118.0",
"proxy=none"
],
"beta": [
"build=1.0.20.0",
"proxy=http"
]
}
res = {}
for k,v in data.items():
res[k] = v[0].split('=')[1] if 'build=' in v[0] else v[1].split('=')[1]
Or using dictionary comprehension:
res = {k: v[0].split('=')[1] if 'build=' in v[0] else v[1].split('=')[1] for k,v in data.items()}
Output:
>>> res
{'xyz': '1.0.127.0', 'abc': '1.0.44.0', 'alfa': '1.0.118.0', 'beta': '1.0.20.0'}
Just iterate and keep the key whose value matches
output_keys = [key for key, value in myjsons if value[0] == 'build=.....']
there is not a fast way to do it without iterating, since dictionaries are intended for lookup on keys, not values

check if the value in a dict is not empty?

I have a dict theaterinfo like this :
"Showtimes":{
"New York": [
{
"Times": {},
"theaterid": 61,
}
]
"Ohio": [
{
"Times": {'2015-01-10',
'2015-01-11'},
"theaterid": 1,
}
]
}
How can I deal with that if Times in empty,don't print it out??
An empty dictionary evaluates to a boolean False while a non-empty dict evaluates to True, so you can write
if my_dict['Times']:
print(my_dict['Times'])
You need to iterate over the dict["Showtimes"] items then access the dict in the list using the Times key and check using an if which will return False for an empty dict.
d = {"Showtimes":{
"New York": [
{
"Times": {},
"theaterid": 61,
}
],
"Ohio": [
{
"Times": {'2015-01-10',
'2015-01-11'},
"theaterid": 1,
}
]
}}
for k,v in d["Showtimes"].iteritems():
if v[0]["Times"]:
print(k,v)
('Ohio', [{'theaterid': 1, 'Times': set(['2015-01-10', '2015-01-11'])}])
One thing to be careful of is if you have a value like 0, this will also return False so if you only want to check if the value is an empty dict use if v[0]["Times"] != {}
If you want to check all values of Times and only print the full dict if there are no empty Times values you can use all which will short circuit on the first occurrence of an empty value:
if all(v[0]["Times"] for v in d["Showtimes"].itervalues()):
print(d)
Or reverse the logic with any:
if not any(not v[0]["Times"] for v in d["Showtimes"].itervalues()):
print(d)
If there is a chance a dict won't have a Times key use v[0].get("Times",1)

Categories

Resources