How to retrieve values from list: python - python

Summary: I have a list
list = [
{
'id': '1',
'elements': 'A',
'table': 'maps/partials/a.html',
'chart': 'maps/partials/charts/a.html',
},
{
'id': '2',
'elements': 'B',
'table': 'maps/partials/census/b.html',
'chart': 'maps/partials/charts/b.html',
},
{
'id': '3',
'elements': ('C','D','E','F'), //i believe it is wrong
'table': 'maps/partials/census/common.html',
'chart': 'maps/partials/charts/common.html',
},]
some_arr = ['E','2011','English','Total']
I want to compare elements with items in some_arr.
and i am doing this to get list and compare it with some_arr.
for data in list:
for i in range(len(some_arr)):
if data['elements'] == some_arr[i]:
print(data['id'])
As you can see in 'id':3 section_title has 4 values. How do i compare elements here with some_arr.

If you want to find any matches:
lst = [
{
'id': '1',
'elements': 'A',
'table': 'maps/partials/a.html',
'chart': 'maps/partials/charts/a.html',
},
{
'id': '2',
'elements': 'B',
'table': 'maps/partials/census/b.html',
'chart': 'maps/partials/charts/b.html',
},
{
'id': '3',
'elements': ('C','D','E','F'),
'table': 'maps/partials/census/common.html',
'chart': 'maps/partials/charts/common.html',
}]
some_arr = ['E','2011','English','Total']
st = set(some_arr)
from collections import Iterable
for d in lst:
val = d["elements"]
if isinstance(val, Iterable) and not isinstance(val, str):
if any(ele in st for ele in val):
print(d["id"])
else:
if val in st:
print(d["id"])
Making a set of all the elements in some_arr will give you O(1) lookups, using isinstance(val, Iterable) and not isinstance(val, str) will catch any iterable value like a list, tuple etc.. and avoid iterating over a string which could give you false positives as "F" is in "Foo".
any will short circuit on the first match so if you actually want to print id for every match then use a for loop. Lastly if you are using python2 use basestring instead of str.

You can use set.intersection to get the intersection between them but before you need to check that if it's a tuple then use intersection.
Also in the first case you can use in to check the membership to check if data['elememnt'] in in some_arr then print data['id']:
for data in list:
d=data['elements']
if isinstance(d,tuple):
if set(d).intersection(some_arr):
print(data['id'])
if d in some_arr:
print(data['id'])

Related

How do I replace single quotes with double quotes in a python array without replacing the single quotes in the json values?

I have an array called managable:
r = requests.get("https://discord.com/api/v8/users/#me/guilds", headers = {
"Authorization": f"Bearer {access_token}"
})
guilds = r.json()
managable = []
for guild in guilds:
if int(guild["permissions"]) & 32 != 0:
managable.append(guild)
where I replace some boolean values in it:
strmanagable = str(managable).replace("True", '"true"').replace("False", '"false"').replace("None", '"none"')
and it returns an array like this:
[{'id': '0', 'name': '\'something\''}, {'id': '1', 'name': '\'two\''}]
I would like to replace the single quotes with double quotes in the array above, without replacing the single quotes in the json values.
I tried using the replace function (strmanagable.replace("'", "\"")), but it replaces single quotes in the json values too, which I don't want.
#snakecharmerb solved my question, I just had to convert managable to json
Are you look for this function json.dumps()? It converts the list into a string literal, then True becomes 'true' automatically
import json
lis1 = [{'id': '0', 'name': True}, {'id': '1', 'name': False}, {'id': '2', 'name': 'two'}]
lis1 = json.dumps(lis1)
Output
'[{"id": "0", "name": true}, {"id": "1", "name": false}, {"id": "2", "name": "two"}]'
Then if you need to convert it back, do this
lis2 = json.loads(lis1)
print(lis2)
[{'id': '0', 'name': True},
{'id': '1', 'name': False},
{'id': '2', 'name': 'two'}]

Python - How to flatten JSON message in pandas/JSON

I have a JSON message as below
JSON_MSG = {
'Header': {
'Timestamp': '2020-10-25T02:49:25.489Z',
'ID': '0422',
'msgName': 'Order',
'Source': 'OrderSys'
},
'CustomerOrderLine': [
{
**'Parameter'**: [
{'ParameterID': 'ACTIVATION_DATE', 'ParameterValue': '2020-10-25'},
{'ParameterID': 'CYCLES', 'ParameterValue': '1'},
{'ParameterID': 'EXPIRY_PERIOD', 'ParameterValue': '30'},
{'ParameterID': 'MAX_NUMBER', 'ParameterValue': '1'}
],
'Subscription': {
'Sub': '3020611',
'LoanAcc': '',
'CustomerAcc': '2020002',
'SubscriptionCreatedDate': '2020-06-23T14:42:30Z',
'BillingAcc': '40010101',
'SubscriptionContractTerm': '12',
'ServiceAcc': '11111',
'SubscriptionStatus': 'Active'
},
'PaymentOpt': 'Upfront',
'OneTimeAmt': '8.0',
'RecurringAmt': '0.0'
'BeneficiaryID': '',
'CustomerOrderID': '111',
'OrderLineCreatedDate': '2020-10-25T02:47:18Z',
'ProductOfferingPriceId': 'PP_6GB_Booster',
'ParentCustomerOrderLineID': '',
'OrderLineRequestedDate': '2020-10-25T00:00:00.000Z',
'ProductCategoryId': 'PRODUCT_OFFER',
'OrderLinePurposeName': 'ADD',
'OrderQuantity': '1.0',
'CustomerOrderLineID': '11111',
'OrderLineDeliveryAddress': {
'OrderLineDeliveryPostCode': '',
'OrderLineDeliveryTown': '',
'OrderLineDeliveryCounty': '',
'OrderLineDeliveryCountryName': ''
},
'ProductInstanceID': '95',
'ProductOfferingId': 'OFF_6GBBOOST_MONTHLY'
}
]
}
I need to flatten the JSON message and convert it into rows and capture the row count/record count
(or)
I need to find out how many elements are present under the nested array Parameter
as this would give me same result as that of flattened JSON(because Parameter is the innermost array)
So far i have tried the below code
data = json.loads(JSON_MSG)
list1 = data['CustomerOrderLine']
rec_count = len(list1)
but this code gives the outer list's result only i.e. 1
as CustomerOrderLine contains only one structs
I need the record/row count as 4 (Parameter array has 4 structs)
Not the prettiest one, but you could try something like:
list1 = JSON_MSG['CustomerOrderLine'][0]['Parameter']
To get 'Parameter' sizes of all elements, you can use list comprehension:
data = json.loads(JSON_MSG)
sizes = [len(order.get('Parameter')) for order in data.get('CustomerOrderLine', [])]

Travers through a nested json object and store values- Python

This is a follow up on this question. Question
Also this question is similar but does not solve my problem Question2
I am trying to parse a nested json to get Check how many children a specific location has, I am trying to check if "children:" = None and increment counter to check how many levels down i need to go in order to get the lowest child, or
A more efficient solution would be:
I need to get all the child values into a list and keep going until "children:" = None.
The Json object can increase in the amount of children so we can have multiple level of children, Which can get messy if I want to nest the list and get the values, How could I do it dynamically?
{
'locationId': 'location1',
'name': 'Name',
'type': 'Ward',
'patientId': None,
'children': [{
'locationId': 'Child_location2',
'name': 'Name',
'type': 'Bed',
'patientId': None,
'children': [{
'locationId': 'Child_Child_location3',
'name': 'Name',
'type': 'HospitalGroup',
'patientId': None,
'children': None
}]
}, {
'locationId': 'location4',
'name': 'Name',
'type': 'Hospital',
'patientId': None,
'children': None
}, {
'locationId': 'location5',
'name': 'Name',
'type': 'Bed',
'patientId': None,
'children': None
}, {
'locationId': 'location6',
'name': 'Name',
'type': 'Bed',
'patientId': None,
'children': None
}, {
'locationId': 'location27',
'name': 'Name',
'type': 'Bed',
'patientId': None,
'children': None
}]
}
I tried to do something like this
import requests
def Get_Child(URL, Name):
headers = {
'accept': 'text/plain',
}
response = requests.get(
URL + Name,
headers=headers)
json_data = response.json()
print (json_data)
list = []
for locationId in json_data['locationId']:
list.append(locationId)
for children in locationId['children']:
list.append(children)
but that give me the following error,
for children in locationId['locationId']: TypeError: string indices must be integers
Your code shows append, but you ask for a count. Here is a recursive way to get the number of children in this JSON if I am understanding you correctly:
def get_children(body, c=1):
if not body.get('children'):
c += 1
elif isinstance(body.get('children'), list):
c += 1
for subchild in body.get('children'):
c += 1
get_children(subchild, c)
return c
counts = get_children(your_json_blob)
print(counts)
>>> 7
Edit: I purposely did not use if/else because I don't know if you can have subchildren that are dict rather than list which would mean you would need extra conditions, but that's up to you if that ends up being the case.
I found a solution fro my problem,
The following code will get all the children and append them to a list
class Children():
def Get_All_Children(self,json_input, lookup_key):
if isinstance(json_input, dict):
for k, v in json_input.items():
if k == lookup_key:
yield v
else:
yield from self.Get_All_Children(v, lookup_key)
elif isinstance(json_input, list):
for item in json_input:
yield from self.Get_All_Children(item, lookup_key)
for locations in self.Get_All_Children(self.json_data, 'locationId'):
self.mylist.append(locations)

KeyError: 'name' Why can't I use 'name'?

I wanna make a dictionary has name's key & data.In views.py I wrote
data_dict ={}
def try_to_int(arg):
try:
return int(arg)
except:
return arg
def main():
book4 = xlrd.open_workbook('./data/excel1.xlsx')
sheet4 = book4.sheet_by_index(0)
data_dict_origin = OrderedDict()
tag_list = sheet4.row_values(0)[1:]
for row_index in range(1, sheet4.nrows):
row = sheet4.row_values(row_index)[1:]
row = list(map(try_to_int, row))
data_dict_origin[row_index] = dict(zip(tag_list, row))
if data_dict_origin['name'] in data_dict:
data_dict[data_dict_origin['name']].update(data_dict_origin)
else:
data_dict[data_dict_origin['name']] = data_dict_origin
main()
When I printed out data_dict,it is
OrderedDict([(1, {'user_id': '100', 'group': 'A', 'name': 'Tom', 'dormitory': 'C'}), (2, {'user_id': '50', 'group': 'B', 'name': 'Blear', 'dormitory': 'E'})])
My ideal dictionary is
dicts = {
Tom: {
'user_id': '100',
'group': 'A',
'name': 'Tom',
'dormitory': 'C'
},
Blear: {
},
}
How should I fix this?What should I write it?
The code is using the wrong key in the dictionary. The keys are 1, 2, and do not have the name key. You can use this code instead:
for value in data_dict.values():
if value['name'] in data_dict:
data_dict[value['name']].update(value)
else:
data_dict[value['name']] = value
Your data_dict_origin has numbers as keys and dicts as values (which technically makes it a sparse array of dicts). The "name" key exists in those dicts, not in your data_dict.

How to retrieve particular values from a list: python

I have a list of items
list = [{
'id': '1',
'elements': 'A',
'table': 'path/to/table1',
'chart': 'path/to/chart1',
},
{
'id': '2',
'elements': 'B',
'table': 'path/to/table2',
'chart': 'path/to/chart2',
},
{
'id': '3',
'elements': 'C',
'table': 'path/to/table3',
'chart': 'path/to/chart3',
},]
selectionsFromTable = [{('A','2011','Table','Total'),
('C','2011','Bar','Total'),
('B','Pie','2001','Total')}]
Compare list['elements'] with selectionsFromTable items and if elem in selectionsFromTable == list['elements'] then append its respective table or chart to arr[].
Assume selectionsFromTable is form data getting from jquery. The index values and position of items always changes here.
i am doing this.
arr = []
for data in list:
if data['elements'] in selectionsFromTable: # Suggest condition here
inner = []
if 'Table' in selectionsFromTable:
print("table")
inner.append({'id': data['id'],
'section_title': data['elements'],
'tableorChart': data['table'],
})
elif 'Bar' in selectionsFromTable or 'Pie' in selectionsFromTable :
print("chart")
inner.append({'id': data['id'],
'section_title': data['elements'],
'tableorChart': data['chart'],
})
arr.append(inner)
I believe it is wrong, kindly suggest me logic here. I am not able to go to "elif" condition as my selectionsFromTable contains "Table".
According to the example you have given, the following check would not work-
data['elements'] in selectionsFromTable
This is because, selectionsFromTable , contains set types, whereas data['elements'] is a string . You want to check inside each element (set) in selectionsFromTable .
A simple way to do this -
arr = []
for data in list:
elem = next((s for s in selectionsFromTable if data['elements'] in s), None)
if elem:
inner = []
if 'Table' in elem:
print("table")
inner.append({'id': data['id'],
'section_title': data['elements'],
'tableorChart': data['table'],
})
elif ('Bar' in elem) or ('Pie' in elem):
print("chart")
inner.append({'id': data['id'],
'section_title': data['elements'],
'tableorChart': data['chart'],
})
arr.append(inner)
Main change would be the line -
elem = next((s for s in selectionsFromTable if data['elements'] in s), None)
What this does is that it either tries to take the first element in selectionsFromTable in which data['elements'] , or if no such elements exists (that is the generator expression did not yield even a single value) , it returns None .
Then in next line we check if elem is not None and then do similar logic after that based on elem (not selectionsFromTable ).
Also, you should not used list as the name of a variable, it would end up masking the list() built-in function and you would not be able to use it afterwards in the same script.
Example/Demo -
>>> list = [{
... 'id': '1',
... 'elements': 'A',
... 'table': 'path/to/table1',
... 'chart': 'path/to/chart1',
... },
... {
... 'id': '2',
... 'elements': 'B',
... 'table': 'path/to/table2',
... 'chart': 'path/to/chart2',
... },
... {
... 'id': '3',
... 'elements': 'C',
... 'table': 'path/to/table3',
... 'chart': 'path/to/chart3',
... },]
>>>
>>> selectionsFromTable = [{'A','2011','Table','Total'},
... {'C','2011','Bar','Total'},
... {'B','Pie','2001','Total'}]
>>> arr = []
>>> for data in list:
... elem = next((s for s in selectionsFromTable if data['elements'] in s), None)
... if elem:
... inner = []
... if 'Table' in elem:
... print("table")
... inner.append({'id': data['id'],
... 'section_title': data['elements'],
... 'tableorChart': data['table'],
... })
... elif ('Bar' in elem) or ('Pie' in elem):
... print("chart")
... inner.append({'id': data['id'],
... 'section_title': data['elements'],
... 'tableorChart': data['chart'],
... })
... arr.append(inner)
...
table
chart
chart
>>> import pprint
>>> pprint.pprint(arr)
[[{'id': '1', 'section_title': 'A', 'tableorChart': 'path/to/table1'}],
[{'id': '2', 'section_title': 'B', 'tableorChart': 'path/to/chart2'}],
[{'id': '3', 'section_title': 'C', 'tableorChart': 'path/to/chart3'}]]

Categories

Resources