I have following nested dictionary,
Data = [{'seriesId': 'Food and Beverage',
'forecastPoint': '2020-08-26T00:00:00Z',
'rowId': 35,
'timestamp': '2020-08-27T00:00:00.000000Z',
'predictionValues': [{'value': 32.5133330947, 'label': 'Volume (actual)'}],
'forecastDistance': 1,
'prediction': 32.5133330947},
{'seriesId': 'Food and Beverage',
'forecastPoint': '2020-08-26T00:00:00Z',
'rowId': 36,
'timestamp': '2020-08-28T00:00:00.000000Z',
'predictionValues': [{'value': 30.2438893873, 'label': 'Volume (actual)'}],
'forecastDistance': 2,
'prediction': 30.2438893873}]
However I want to bring that dictionary into following form dictionary where I only want to access the value from predictionValues and get other keys as it is.
Expected output should be a dictionary
Data = [{'seriesId': 'Food and Beverage',
'forecastPoint': '2020-08-26T00:00:00Z',
'rowId': 35,
'timestamp': '2020-08-27T00:00:00.000000Z',
'value': 32.5133330947,
'forecastDistance': 1,
'prediction': 32.5133330947},
{'seriesId': 'Food and Beverage',
'forecastPoint': '2020-08-26T00:00:00Z',
'rowId': 36,
'timestamp': '2020-08-28T00:00:00.000000Z',
'value': 30.2438893873,
'forecastDistance': 2,
'prediction': 30.2438893873}]
Try this
for d in Data:
d.update({'value': d.pop('predictionValues')[0].pop('value')})
Use the following
for i in range(len(Data)):
Data[i]['predictionValues'] = Data[i]['predictionValues'][0]['value']
The original list of dictionaries seems to contain the prediction value already, so just deleting the predictionValue entry should do the trick
for dictionary in Data:
del dictionary['predictionValues']
A bit of a play on list comprehension with dict :
[
dict( (key, value)
if not isinstance(value, list)
else ("value", entry[key][0]["value"])
for key, value in entry.items()
)
for entry in Data
]
[{'seriesId': 'Food and Beverage',
'forecastPoint': '2020-08-26T00:00:00Z',
'rowId': 35,
'timestamp': '2020-08-27T00:00:00.000000Z',
'value': 32.5133330947,
'forecastDistance': 1,
'prediction': 32.5133330947},
{'seriesId': 'Food and Beverage',
'forecastPoint': '2020-08-26T00:00:00Z',
'rowId': 36,
'timestamp': '2020-08-28T00:00:00.000000Z',
'value': 30.2438893873,
'forecastDistance': 2,
'prediction': 30.2438893873}]
Related
I was tasked to create a CRUD program using Python dictionaries. I need to write code to check if the inputted key and value already exists in the dictionary, so here is the code of dictionary plus the input that prompt the user to search for ID:
products = [
{'id': 1, 'name': 'Light bulb', 'price': 100, 'stock': 16},
{'id': 2, 'name': 'Measuring tape', 'price': 200, 'stock': 34},
{'id': 3, 'name': 'Fan', 'price': 120, 'stock': 79},
{'id': 4, 'name': 'Flat shoes', 'price': 260, 'stock': 47},
{'id': 5, 'name': 'Swiss Army knife', 'price': 80, 'stock': 12},
{'id': 6, 'name': 'Guitar', 'price': 193, 'stock': 25},
{'id': 7, 'name': 'Marble', 'price': 30, 'stock': 45},
{'id': 8, 'name': 'Stapler', 'price': 220, 'stock': 78},
{'id': 9, 'name': 'Wrench and hammer', 'price': 65, 'stock': 12}
]
id_search = int(input("Enter ID product you want to search: ")
I wanted to make the if-else statement to see if the ID exists in the products dictionary, otherwise display the message that the ID is not found. I tried the following
if id_search in products:
print("Product ID found")
else:
print("Product ID not found")
But the result is always "Product ID not found".
You have a list of dicts not just a dict. You have to search through list of dicts:
found = False
for product in products:
if product.get("id") == id_search:
found = True
break
print(found)
Note that if your dicts are sorted, you probably can use binary search.
if len([[*my_dict.values()][0] for my_dict in products if [*my_dict.values()][0] == id_search]) > 0:
print("Product ID found")
else:
print("Product ID not found")
I have a complex situation which I hope to solve and which might profit us all. I collected data from my API, added a pagination and inserted the complete data package in a tuple named q1 and finally I have made a dictionary named dict_1of that tuple which looks like this:
dict_1 = {100: {'ID': 100, 'DKSTGFase': None, 'DK': False, 'KM': None,
'Country: {'Name': GE', 'City': {'Name': 'Berlin'}},
'Type': {'Name': '219'}, 'DKObject': {'Name': '8555', 'Object': {'Name': 'Car'}},
'Order': {'OrderId': 101, 'CreatedOn': '2018-07-06T16:54:36.783+02:00',
'ModifiedOn': '2018-07-06T16:54:36.783+02:00',
'Name': Audi, 'Client': {‘1’ }}, 'DKComponent': {'Name': ‘John’}},
{200: {'ID': 200, 'DKSTGFase': None, 'DK': False, ' KM ': None,
'Country: {'Name': ES', 'City': {'Name': 'Madrid'}}, 'Type': {'Name': '220'},
'DKObject': {'Name': '8556', 'Object': {'Name': 'Car'}},
'Order': {'OrderId': 102, 'CreatedOn': '2018-07-06T16:54:36.783+02:00',
'ModifiedOn': '2018-07-06T16:54:36.783+02:00',
'Name': Mercedes, 'Client': {‘2’ }}, 'DKComponent': {'Name': ‘Sergio’}},
Please note that in the above dictionary I have just stated 2 records. The actual dictionary has 1400 records till it reaches ID 1500.
Now I want to 2 things:
I want to change some keys for all the records. key DK has to become DK1. Key Name in Country has to become Name1 and Name in Object has to become 'Name2'
The second thing I want is to make a dataFrame of the whole bunch of data. My expected outcome is:
This is my code:
q1 = response_2.json()
next_link = q1['#odata.nextLink']
q1 = [tuple(q1.values())]
while next_link:
new_response = requests.get(next_link, headers=headers, proxies=proxies)
new_data = new_response.json()
q1.append(tuple(new_data.values()))
next_link = new_data.get('#odata.nextLink', None)
dict_1 = {
record['ID']: record
for tup in q1
for record in tup[2]
}
#print(dict_1)
for x in dict_1.values():
x['DK1'] = x['DK']
x['Country']['Name1'] = x['Country']['Name']
x['Object']['Name2'] = x['Object']['Name']
df = pd.DataFrame(dict_1)
When i run this I receive the following Error:
Traceback (most recent call last):
File "c:\data\FF\Desktop\Python\PythongMySQL\Talky.py", line 57, in <module>
x['Country']['Name1'] = x['Country']['Name']
TypeError: 'NoneType' object is not subscriptable
working code
lists=[]
alldict=[{100: {'ID': 100, 'DKSTGFase': None, 'DK': False, 'KM': None,
'Country': {'Name': 'GE', 'City': {'Name': 'Berlin'}},
'Type': {'Name': '219'}, 'DKObject': {'Name': '8555', 'Object': {'Name': 'Car'}},
'Order': {'OrderId': 101, 'CreatedOn': '2018-07-06T16:54:36.783+02:00',
'ModifiedOn': '2018-07-06T16:54:36.783+02:00',
'Name': 'Audi', 'Client': {'1' }}, 'DKComponent': {'Name': 'John'}}}]
for eachdict in alldict:
key=list(eachdict.keys())[0]
eachdict[key]['DK1']=eachdict[key]['DK']
del eachdict[key]['DK']
eachdict[key]['Country']['Name1']=eachdict[key]['Country']['Name']
del eachdict[key]['Country']['Name']
eachdict[key]['DKObject']['Object']['Name2']=eachdict[key]['DKObject']['Object']['Name']
del eachdict[key]['DKObject']['Object']['Name']
lists.append([key, eachdict[key]['DK1'], eachdict[key]['KM'], eachdict[key]['Country']['Name1'],
eachdict[key]['Country']['City']['Name'], eachdict[key]['DKObject']['Object']['Name2'], eachdict[key]['Order']['Client']])
pd.DataFrame(lists, columns=[<columnNamesHere>])
Output:
{100: {'ID': 100,
'DKSTGFase': None,
'KM': None,
'Country': {'City': {'Name': 'Berlin'}, 'Name1': 'GE'},
'Type': {'Name': '219'},
'DKObject': {'Name': '8555', 'Object': {'Name2': 'Car'}},
'Order': {'OrderId': 101,
'CreatedOn': '2018-07-06T16:54:36.783+02:00',
'ModifiedOn': '2018-07-06T16:54:36.783+02:00',
'Name': 'Audi',
'Client': {'1'}},
'DKComponent': {'Name': 'John'},
'DK1': False}}
datainput = {'thissong-fav-user:type1-chan-44-John': [{'Song': 'Rock',
'Type': 'Hard',
'Price': '10'}],
'thissong-fav-user:type1-chan-45-kelly-md': [{'Song': 'Rock',
'Type': 'Soft',
'Price': '5'}]}
Outputrequired:
{'thissong-fav-user:type1-chan-44-John': [{key:'Song',Value:'Rock'},
{key:'Type', Value:'Hard'},
{Key: 'Price', Value:'10'}],
'thissong-fav-user:type1-chan-45-kelly-md': [{key:'Song',Value:'Rock'},
{key:'Type', Value:'Soft'},
{Key: 'Price', Value:'5'}]}
I started with below, which gives me an inner nested pattern not sure how I can get the desired output.
temps = [{'Key': key, 'Value': value} for (key, value) in datainput.items()]
Here is how:
datainput = {'thissong-fav-user:type1-chan-44-John': [{'Song': 'Rock',
'Type': 'Hard',
'Price': '10'}],
'thissong-fav-user:type1-chan-45-kelly-md': [{'Song': 'Rock',
'Type': 'Soft',
'Price': '5'}]}
temps = {k:[{'Key':a, 'Value':b}
for a,b in v[0].items()]
for k,v in datainput.items()}
print(datainput)
Output:
{'thissong-fav-user:type1-chan-44-John': [{'Key': 'Song', 'Value': 'Rock'},
{'Key': 'Type', 'Value': 'Hard'},
{'Key': 'Price', 'Value': '10'}],
'thissong-fav-user:type1-chan-45-kelly-md': [{'Key': 'Song', 'Value': 'Rock'},
{'Key': 'Type', 'Value': 'Soft'},
{'Key': 'Price', 'Value': '5'}]}
I believe the way of having taken the input is fine but in order to get the desired output, you got to take the inputs initially, then key-value pair and finally iterate.
datainput = {'thissong-fav-user:type1-chan-44-John': [{'Song': 'Rock',
'Type': 'Hard',
'Price': '10'}],
'thissong-fav-user:type1-chan-45-kelly-md': [{'Song': 'Rock',
'Type': 'Soft',
'Price': '5'}]}
datainput = {k:[{'Key':a, 'Value':b} for a,b in v[0].items()] for k,v in datainput.items()}
print(datainput)
Most probably, you'll get the desired output in this fashion.
I am given a list of lists, similar to the following. I am very new to Python
[
{'id': 1244},
{'name': 'example.com'},
{'monitoring_enabled': 'Yes'},
{'monitoring_url': 'http://www.example.com/'},
{'monitoring_page_url': 'http://www.example.com/products-spool-chain-overview.htm'},
{'monitoring_text_string': 'quality product'},
]
[
{'id': 1245},
{'name': 'example.com'},
{'monitoring_enabled': 'Yes'},
{'monitoring_url': 'http://www.example.com/'},
{'monitoring_page_url': 'http://www.example.com/products-spool-chain-overview.htm'},
{'monitoring_text_string': 'quality product'},
]
[
{'id': 1246},
{'name': 'example.com'},
{'monitoring_enabled': 'Yes'},
{'monitoring_url': 'http://www.example.com/'},
{'monitoring_page_url': 'http://www.example.com/products-spool-chain-overview.htm'},
{'monitoring_text_string': 'quality product'},
]
How can I get the "name" value from this, without having to nest loops?
My current code is:
for _row in _rs:
print(_row)
print(_row["name])
However, I am receiving an error message: TypeError: list indices must be integers, not str
So, how can I accomplish this?
if it trully a list of list there is a comma between each list. then you can easily do that:
for i in x:
print(i[1]['name'])
How does this look?
l = [{'id': 1244}, {'name': 'example.com'}, ...]
names = e['name'] for e in l if 'name' in e]
print(names)
>>> ['example.com']
You can move around the list and check if each dictionary has the "name" key, and print the result if yes.
list1 = [{'id': 1244},
{'name': 'example.com'},
{'monitoring_enabled': 'Yes'},
{'monitoring_url': 'http://www.example.com/'},
{'monitoring_page_url': 'http://www.example.com/products-spool-chain-overview.htm'},
{'monitoring_text_string': 'quality product'}]
for dictionary in list1:
if "name" in dictionary.keys(): # Whether the dictionary looks like {"name": ...}
print(dictionary["name"])
break # Exit the loop now that we have the name, instead of going through the whole list.
Edit: your input is broken. Before being able to work on it, you want to change the function that gives you what you showed in the OP into that:
[ # <-- outer list starts
[
{'id': 1244},
{'name': 'example.com'},
{'monitoring_enabled': 'Yes'},
{'monitoring_url': 'http://www.example.com/'},
{'monitoring_page_url': 'http://www.example.com/products-spool-chain- overview.htm'},
{'monitoring_text_string': 'quality product'},
], # <--
[
{'id': 1245},
{'name': 'example.com'},
{'monitoring_enabled': 'Yes'},
{'monitoring_url': 'http://www.example.com/'},
{'monitoring_page_url': 'http://www.example.com/products-spool-chain-overview.htm'},
{'monitoring_text_string': 'quality product'},
], # <--
[
{'id': 1246},
{'name': 'example.com'},
{'monitoring_enabled': 'Yes'},
{'monitoring_url': 'http://www.example.com/'},
{'monitoring_page_url': 'http://www.example.com/products-spool-chain-overview.htm'},
{'monitoring_text_string': 'quality product'},
]
] # <-- outer list ends
Even better:
lists_of_dicts = [
[{'id': 1244,
'name': 'example.com',
'monitoring_enabled': 'Yes',
'monitoring_url': 'http://www.example.com/',
'monitoring_page_url': 'http://www.example.com/products-spool-chain- overview.htm',
'monitoring_text_string': 'quality product'}],
[{'id': 1245,
'name': 'example.com',
'monitoring_enabled': 'Yes',
'monitoring_url': 'http://www.example.com/',
'monitoring_page_url': 'http://www.example.com/products-spool-chain- overview.htm',
'monitoring_text_string': 'quality product'}],
[{'id': 1246,
'name': 'example.com',
'monitoring_enabled': 'Yes',
'monitoring_url': 'http://www.example.com/',
'monitoring_page_url': 'http://www.example.com/products-spool-chain- overview.htm',
'monitoring_text_string': 'quality product'}]
]
Objective: Append items from value['itemArray'] to Products['Items'] - see function fba_orders
Problem: The Current code only appends the last item of value['itemArray'] to Products['Items']
Current Output:
{'Items': [{'SellerFulfillmentOrderItemId': 266804219, 'SellerSKU': 'IX-GZ31-31K6', 'Quantity': 1}, {'SellerFulfillmentOrderItemId': 266804219, 'SellerSKU': 'IX-GZ31-31K6', 'Quantity': 1}]}
Correct Output would be:
{'Items': [{'SellerFulfillmentOrderItemId': 266804218, 'SellerSKU': 'KM-090914-840-BEARLAPTOP', 'Quantity': 1}, {'SellerFulfillmentOrderItemId': 266804219, 'SellerSKU': 'IX-GZ31-31K6', 'Quantity': 1}]}
Code:
import sys
VALUE = {'amountPaid': '43.38',
'amountSaved': 0.0,
'buyerCheckoutMessage': '',
'buyerUserID': 13182254,
'buyerUserName': 'W5Tiny',
'checkoutStatus': {'status': 'Complete'},
'createdTime': '2015-06-30T22:41:01Z',
'creatingUserRole': 'Buyer',
'itemArray': [{'item': {'itemID': 266804218,
'price': '21.1',
'quantity': 1,
'sellerInventoryID': 'KM-090914-840-BEARLAPTOP',
'sk': 'KM-090914-840-BEARLAPTOP',
'title': u"VTech Bear's Baby Laptop, Blue [Toy]"}},
{'item': {'itemID': 266804219,
'price': '22.28',
'quantity': 1,
'sellerInventoryID': 'IX-GZ31-31K6',
'sk': 'IX-GZ31-31K6',
'title': 'Toy State Caterpillar Push Powered Rev It Up Dump Truck [Toy]'}}],
'orderID': 34013525,
'orderStatus': 'Completed',
'paidTime': '2015-06-30T22:50:38Z',
'shippingAddress': {'addressID': 15798541,
'cityName': 'Nashville',
'country': 'US',
'countryName': None,
'name': 'UNKNOWN',
'postalCode': '37221',
'stateOrProvince': 'TN',
'street1': '123 BOOGIE DRIVE',
'street2': None},
'shippingDetails': {'amount': '0.0',
'insuranceFee': 0,
'servicesArray': [],
'shippingService': 'Standard shipping'},
'subtotal': 43.38,
'taxAmount': 0.0,
'total': '43.38',
'transactionArray': {'transaction': {'buyer': {'email': 'fakewilson259612#hotmail.com'},
'finalValueFee': '0.0',
'providerID': '11V84334FD304010L',
'providerName': 'Paypal'}}}
def fba_order():
address = {}
products = {'Items': []}
item = {}
Items = []
address['City'] = VALUE['shippingAddress']['cityName']
address['CountryCode'] = VALUE['shippingAddress']['country']
address['Line1'] = VALUE['shippingAddress']['street1']
address['Line2'] = VALUE['shippingAddress']['street2']
address['Name'] = VALUE['shippingAddress']['name']
address['PostalCode'] = VALUE['shippingAddress']['postalCode']
address['StateOrProvinceCode'] = VALUE['shippingAddress']['stateOrProvince']
for items in VALUE['itemArray']:
item['Quantity'] = items['item']['quantity']
item['SellerFulfillmentOrderItemId'] = items['item']['itemID']
item['SellerSKU'] = items['item']['sk']
products['Items'].append(item)
continue
print address, '\n', products
if __name__ == '__main__':
sys.exit(fba_order())
You are reusing the dictionary referenced by item over and over again; appending this one dictionary won't create a new copy. Rather, you are adding multiple references to that one dictionary. As you continue to alter the dictionary all those references will show those changes.
Better produce an entirely new dictionary for each loop iteration:
for items in VALUE['itemArray']:
item = {
'Quantity': items['item']['quantity'],
'SellerFulfillmentOrderItemId': items['item']['itemID']
'SellerSKU': items['item']['sk'],
}
products['Items'].append(item)
The issue is that you are creating item outside the for loop and then just changing the values inside the for loop and appending it to the list.
dictionaries are reference, and hence even after appending to products['Items'] list if you change the item dictionary it will make changes to the item that was appended to the list.
You want to initialize item to a new dictionary inside the for loop.
Example -
def fba_order():
address = {}
products = {'Items': []}
Items = []
address['City'] = VALUE['shippingAddress']['cityName']
address['CountryCode'] = VALUE['shippingAddress']['country']
address['Line1'] = VALUE['shippingAddress']['street1']
address['Line2'] = VALUE['shippingAddress']['street2']
address['Name'] = VALUE['shippingAddress']['name']
address['PostalCode'] = VALUE['shippingAddress']['postalCode']
address['StateOrProvinceCode'] = VALUE['shippingAddress']['stateOrProvince']
for items in VALUE['itemArray']:
item = {}
item['Quantity'] = items['item']['quantity']
item['SellerFulfillmentOrderItemId'] = items['item']['itemID']
item['SellerSKU'] = items['item']['sk']
products['Items'].append(item)
continue
print address, '\n', products