replacing keys from a dictionary inside a list python - python

I have a list inside a nested dictionary
body = {'Ready Date': '2020-01-31T12:00:00','Shipment Line List': [{'Description': 'Test', 'Weigth': '5',
'Height': '4.0','Length': '2.0', 'Width': '3.0'}, {'Description': 'Test', 'Weigth': '20', 'Height': '5',
'Length': '30', 'Width': '10']}
I want to iterate over the keys in the nested dictionary and replace "Weigth" with the correct spelling "Weight"
I tried this approach, but I am not getting the expected output
key = {"Weigth":"Weight"}
def find_replace(dict_body, dictionary):
# is the item in the dict?
for item in dict_body:
# iterate by keys
if item in dictionary.keys():
# look up and replace
dict_body = dict_body.replace(item, dictionary[item])
# return updated dict
return dict_body
a = find_replace(body,key)
print(a)

I think a better idea in this particular case is to treat everything as a string, replace and back as a dictionary. Because if you have multiple nested keys, it might be just be easier this way in two lines of code:
from ast import literal_eval
body = literal_eval(str(body).replace("Weigth","Weight"))
This outputs:
{'Ready Date': '2020-01-31T12:00:00',
'Shipment Line List': [{'Description': 'Test',
'Height': '4.0',
'Length': '2.0',
'Weight': '5',
'Width': '3.0'},
{'Description': 'Test',
'Height': '5',
'Length': '30',
'Weight': '20',
'Width': '10'}]}

I want to iterate over the keys in the nested dictionary and replace "Weigth" with the correct spelling "Weight"
something like the below
body = {'Ready Date': '2020-01-31T12:00:00', 'Shipment Line List': [{'Description': 'Test', 'Weigth': '5',
'Height': '4.0', 'Length': '2.0', 'Width': '3.0'},
{'Description': 'Test', 'Weigth': '20',
'Height': '5',
'Length': '30', 'Width': '10'}]}
for entry in body['Shipment Line List']:
entry['Weight'] = entry['Weigth']
del entry['Weigth']
print(body)
output
{'Ready Date': '2020-01-31T12:00:00', 'Shipment Line List': [{'Description': 'Test', 'Height': '4.0', 'Length': '2.0', 'Width': '3.0', 'Weight': '5'}, {'Description': 'Test', 'Height': '5', 'Length': '30', 'Width': '10', 'Weight': '20'}]}

Related

TypeError: '<' not supported between instances of 'str' and 'float'

I have a simple Python script that queries an API and parses the JSON data. Specifically, I am trying to find all ids that fall into a rectangle based on given latitude and longitude coordinates. I am having some data type issues since one is being returned as type str and the other as type float. The coordinates are: (37.769754, -122.427050) and, (37.748554, -122.404535).
Below is my code, sample JSON, and the trace.
Code:
import requests
def get_ids():
url = "https://retro.umoiq.com/service/publicJSONFeed?command=vehicleLocations&a=sf-muni&t=0"
response = requests.get(url).json()
id_list = []
for id in response['vehicle']:
lat = id['lat']
lon = id['lon']
if (lat <= 37.769754 and lat >= 37.748554):
if (lon >= -122.427050 and lon <= -122.404535):
id_list.append(id['id'])
return id_list
def main():
print(get_ids())
if __name__ == "__main__":
main()
JSON:
{'lastTime': {'time': '1653259435728'}, 'copyright': 'All data copyright San Francisco Muni 2022.', 'vehicle': [{'routeTag': 'KT', 'predictable': 'true', 'heading': '218', 'speedKmHr': '0', 'lon': '-122.405464', 'id': '1462', 'dirTag': 'KT___O_F20', 'lat': '37.708099', 'secsSinceReport': '33', 'leadingVehicleId': '1487'}, {'routeTag': '33', 'predictable': 'true', 'heading': '165', 'speedKmHr': '35', 'lon': '-122.40744', 'id': '5817', 'dirTag': '33___O_F00', 'lat': '37.763451', 'secsSinceReport': '6'}, {'routeTag': '1', 'predictable': 'true', 'heading': '269', 'speedKmHr': '0', 'lon': '-122.492844', 'id': '5818', 'dirTag': '1____O_F00', 'lat': '37.77985', 'secsSinceReport': '33'}, {'routeTag': '1', 'predictable': 'true', 'heading': '219', 'speedKmHr': '0', 'lon': '-122.493156', 'id': '5819', 'lat': '37.779823', 'secsSinceReport': '6'}, {'routeTag': 'N', 'predictable': 'true', 'heading': '195', 'speedKmHr': '6', 'lon': '-122.457748', 'id': '1453', 'dirTag': 'N____O_F01', 'lat': '37.764671', 'secsSinceReport': '33'}, {'routeTag': '24', 'predictable': 'true', 'heading': '231', 'speedKmHr': '0', 'lon': '-122.412033', 'id': '5813', 'dirTag': '24___I_F00', 'lat': '37.739773', 'secsSinceReport': '20'}, {'routeTag': '1', 'predictable': 'true', 'heading': '80', 'speedKmHr': '0', 'lon': '-122.397522', 'id': '5815', 'dirTag': '1____I_F00', 'lat': '37.795418', 'secsSinceReport': '46'}, {'routeTag': '1', 'predictable': 'true', 'heading': '87', 'speedKmHr': '0', 'lon': '-122.472931', 'id': '5827', 'dirTag': '1____I_F00', 'lat': '37.78437', 'secsSinceReport': '6'}, {'routeTag': 'KT', 'predictable': 'true', 'heading': '330', 'speedKmHr': '32', 'lon': '-122.468117', 'id': '1469', 'dirTag': 'KT___I_F20', 'lat': '37.7290149', 'secsSinceReport': '6'}, {'routeTag': '33', 'predictable': 'true', 'heading': '77', 'speedKmHr': '0', 'lon': '-122.456421', 'id': '5828', 'dirTag': '33___O_F00', 'lat': '37.786957', 'secsSinceReport': '6'}, {'routeTag': '45', 'predictable': 'true', 'heading': '165', 'speedKmHr': '21', 'lon': '-122.406647', 'id': '5829', 'dirTag': '45___I_F00', 'lat': '37.78756', 'secsSinceReport': '6'}
etc...
Trace:
Traceback (most recent call last):
File "/main.py", line 51, in <module>
main()
File "/main.py", line 48, in main
get_ids()
File "/main.py", line 41, in get_ids
if (lat < 37.769754 and lon < -122.427050):
TypeError: '<' not supported between instances of 'str' and 'float'
Try converting the data to floats like so:
lat = float(i['lat'])
lon = float(i['lon'])
This will allow the comparison operators to work correctly when comparing 2 floats.
Keep in mind the operators themselves are wrong (long -179 and lat -179 would fit inside your rectangle).
I took the liberty to improve some of your code and fix the comparison operators:
import requests
VEHICLE_LOCATIONS_URL = "https://retro.umoiq.com/service/publicJSONFeed?command=vehicleLocations&a=sf-muni&t=0"
# (min_lat, max_lat), (min_long, max_long)
BOUNDARIES = ((37.748554, 37.769754), (-122.427050, -122.404535))
def get_ids_in_boundry():
response = requests.get(VEHICLE_LOCATIONS_URL).json()
id_list = []
for vehicle in response['vehicle']:
lat, long = float(vehicle['lat']), float(vehicle['lon'])
if ((BOUNDARIES[0][0] <= lat <= BOUNDARIES[0][1])
and (BOUNDARIES[1][0] <= long <= BOUNDARIES[1][1])):
id_list.append(vehicle['id'])
return id_list
def main():
print(get_ids_in_boundry())
if __name__ == "__main__":
main()
I've changed the URL to be a const, so as the boundaries, and returned the id_list outside of the function. Many other improvements can be added such as asking for boundaries in the function parameter or splitting doing the request and checking the boundaries into 2 different functions.
If I understood everything correctly the aswer is to convert the variables lat and lon to floats.
To do that just modify this in your code
lat = float(i['lat'])
lon = float(i['lon'])

I want to access a subscriptable object in python Programming

I want to retrieve data i.e symbol, id, etc,
List = api.get_activities()
AccountActivity({ 'activity_type': 'FILL',
'cum_qty': '10',
'id': '20211227093208266::0e4e8144-e4ce-4b0f-af54-f35c575e2adb',
'leaves_qty': '0',
'order_id': '4746c3ac-a62b-4208-9098-de0d3a05f071',
'order_status': 'filled',
'price': '137.16',
'qty': '3',
'side': 'buy',
'symbol': 'QDEL',
'transaction_time': '2021-12-27T14:32:08.266871Z',
'type': 'fill'})
List[1]
List[1]["symbol"]
I am facing this error.
'AccountActivity' object is not subscriptable

Convert list of Dictionaries to comma separated string python

i'm trying to convert list of dictionaries to comma separated string , but some extra fields of dictionary are coming
data = [{'groupid': '28', 'name': 'TEST 2', 'internal': '0', 'flags': '0'}, {'groupid':'27', 'name': 'CUSTOMER/TEST 1', 'internal': '0', 'flags': '0'}]
expected output = TEST2,CUSTOMER/TEST 1
my script: s = [','.join(map(str,i.values())) for i in data]
output i'm getting : ['28,TEST 2,0,0', '27,CUSTOMER/TEST 1,0,0']
Try this:
data = [{'groupid': '28', 'name': 'TEST 2', 'internal': '0', 'flags': '0'}, {'groupid':'27', 'name': 'CUSTOMER/TEST 1', 'internal': '0', 'flags': '0'}]
print([d["name"] for d in data])
Output:
['TEST 2', 'CUSTOMER/TEST 1']
For the expected out, you simply need to get the value corresponding to the key name:
s = ','.join(i['name'] for i in data)
Data is defined as dictionary object. Apply elt for filter.
data = [{'groupid': '28', 'name': 'TEST 2', 'internal': '0', 'flags': '0'},
{'groupid':'27', 'name': 'CUSTOMER/TEST 1', 'internal': '0', 'flags': '0'}]
expected output = [elt["name"] for elt in data]
print(expected output)
output = ['TEST 2', 'CUSTOMER/TEST 1']

python: combine lists to dictionary with header

I want to combine two lists in to one dictionary type.
Name = ['John','Mary','Serena','Felicia']
Data = ['26','179','25','164','29','149','29','167']
desirable output in Json format
{"people":[{'Name': 'John',
'Age': '26',
'Height': '179'},
{'Name': 'Mary',
'Age': '25',
'Height': '164'}
{'Name': 'Serena',
'Age': '29',
'Height': '149'}
{'Name': 'Felicia',
'Age': '29',
'Height': '167'} ]
}
I try to combine with list1 = {k: 'Name' for k in Name} but the dictionary
shown 'John' = 'Name' which is reverse of what I need.
a couple of nested zips & slices do the trick to build dicts in a list comprehension, as value of the outer dict:
Name = ['John','Mary','Serena','Felicia']
Data = ['26','179','25','164','29','149','29','167']
result = {'people':[{'Name' : name, 'Age' : age, 'Height' : height}
for name,(age,height) in zip(Name,zip(Data[::2],Data[1::2]))]}
print(result)
prints:
{'people': [{'Name': 'John', 'Height': '179', 'Age': '26'}, {'Name': 'Mary', 'Height': '164', 'Age': '25'}, {'Name': 'Serena', 'Height': '149', 'Age': '29'}, {'Name': 'Felicia', 'Height': '167', 'Age': '29'}]}
if you don't want to create "hard" slices, use itertools.islice, also would be interesting to convert integer values as integer, which avoids the easy trap of lexicographical compare of integers as strings later on:
from itertools import islice
result = {'people':[{'Name' : name, 'Age' : int(age), 'Height' : int(height)}
for name,age,height in zip(Name,islice(Data,None,None,2),islice(Data,1,None,2))]}
(and also thanks to comments, no need to nest zip statements)
result:
{'people': [{'Height': 179, 'Age': 26, 'Name': 'John'},
{'Height': 164, 'Age': 25, 'Name': 'Mary'},
{'Height': 149, 'Age': 29, 'Name': 'Serena'},
{'Height': 167, 'Age': 29, 'Name': 'Felicia'}]}
Using zip:
Name = ['John','Mary','Serena','Felicia']
Data = ['26','179','25','164','29','149','29','167']
dct = {"people": [{'Name': i, 'Age': j, 'Height': k} for i, j, k in zip(Name, Data[::2], Data[1::2])]}
print(dct)
Output:
{'people': [{'Name': 'John', 'Age': '26', 'Height': '179'}, {'Name': 'Mary', 'Age': '25', 'Height': '164'}, {'Name': 'Serena', 'Age': '29', 'Height': '149'}, {'Name': 'Felicia', 'Age': '29', 'Height': '167'}]}
Here's an interesting approach.
>>> Name = ['John','Mary','Serena','Felicia']
>>> Data = ['26','179','25','164','29','149','29','167']
>>> keys = ['Name', 'Age', 'Height']
>>> it = iter(Data)
>>> {'people':[dict(zip(keys,i)) for i in zip(Name, it, it)]}
Can't make it too much more compact than this.
Ouput
{'people': [{'Name': 'John', 'Age': '26', 'Height': '179'}, {'Name': 'Mary', 'Age': '25', 'Height': '164'}, {'Name': 'Serena', 'Age': '29', 'Height': '149'}, {'Name': 'Felicia', 'Age': '29', 'Height': '167'}]}

How to extract the uris lists by regex? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
In my python code , I get strings from the text file like :
a = "[{'index': '1', 'selected': 'true', 'length': '0', 'completedLength': '0', 'path': '', 'uris': [{'status': 'used', 'uri': 'http://www.single.com'}]}]"
b ="[{'index': '1', 'selected': 'true', 'length': '0', 'completedLength': '0', 'path': '', 'uris': [{'status': 'used', 'uri': 'http://www.mirrors.com'}, {'status': 'used', 'uri': 'http://www.mirrors2.com'}]}]"
c ="[{'index': '1', 'selected': 'true', 'length': '103674793', 'completedLength': '0', 'path': '/home/dr/Maher_Al-Muaiqly_(MP3_Quran)/002.mp3', 'uris': []}, {'index': '2', 'selected': 'true', 'length': '62043128', 'completedLength': '0', 'path': '/home/dr/Maher_Al-Muaiqly_(MP3_Quran)/004.mp3', 'uris': []}, {'index': '3', 'selected': 'true', 'length': '57914945', 'completedLength': '0', 'path': '/home/dr/Maher_Al-Muaiqly_(MP3_Quran)/003.mp3', 'uris': []}]"
I want to get the text of the value uris , the output should looks like :
a = [{'status': 'used', 'uri': 'http://www.single.com'}]
b = [{'status': 'used', 'uri': 'http://www.mirrors.com'}, {'status': 'used', 'uri': 'http://www.mirrors2.com'}]
c = [[],[],[]]
Many hours I spent in failed trials to get this result by using the string functions ,
uris = str.split('}, {')
for uri in uris :
uri = uri.split(',')
# and so on ...
but , it work so bad especially in the second case , I hope that anyone can do it by regex or any other way.
They are all python literals. You can use ast.literal_eval. No need to use regular expression.
>>> a = "[{'index': '1', 'selected': 'true', 'length': '0', 'completedLength': '0', 'path': '', 'uris': [{'status': 'used', 'uri': 'http://www.single.com'}]}]"
>>> b = "[{'index': '1', 'selected': 'true', 'length': '0', 'completedLength': '0', 'path': '', 'uris': [{'status': 'used', 'uri': 'http://www.mirrors.com'}, {'status': 'used', 'uri': 'http://www.mirrors2.com'}]}]"
>>> c = "[{'index': '1', 'selected': 'true', 'length': '103674793', 'completedLength': '0', 'path': '/home/dr/Maher_Al-Muaiqly_(MP3_Quran)/002.mp3', 'uris': []}, {'index': '2', 'selected': 'true', 'length': '62043128', 'completedLength': '0', 'path': '/home/dr/Maher_Al-Muaiqly_(MP3_Quran)/004.mp3', 'uris': []}, {'index': '3', 'selected': 'true', 'length': '57914945', 'completedLength': '0', 'path': '/home/dr/Maher_Al-Muaiqly_(MP3_Quran)/003.mp3', 'uris': []}]"
>>> import ast
>>> [x['uris'] for x in ast.literal_eval(a)]
[[{'status': 'used', 'uri': 'http://www.single.com'}]]
>>> [x['uris'] for x in ast.literal_eval(b)]
[[{'status': 'used', 'uri': 'http://www.mirrors.com'}, {'status': 'used', 'uri': 'http://www.mirrors2.com'}]]
>>> [x['uris'] for x in ast.literal_eval(c)]
[[], [], []]
in javascript you can do this
a = a.replace(/^.*uris[^[]*(\[[^\]]*\]).*$/, '\1');
if php would be this a way
$a = preg_replace('/^.*uris[^[]*(\[[^\]]*\]).*$/', '\1', $a);
edit: well I see, it wouldn't do your complete task for 'c' -.-

Categories

Resources