I am trying to create a dictionary lookup variable like this:
lookup = {
u'安徽省':'Anhui',
u'福建省':'Fujian',
u'甘肃省':'Gansu',
u'广东省':'Guangdong',
u'贵州省':'Guizhou',
u'浙江省':'Zhejiang'
}
I am calling an API and it returns the result in Chinese. I want to simply have a look up table to convert it to the English name.
So my code is:
api_response = api.geocode(address, isChina)
if len(api_response['Response']['View']) > 0:
state = lookup[api_response['Response']['View'][0]['Result'][0]['Location']['Address']['State']]
But the error I get is:
2019-07-29 15:35:13.193 | ERROR | __main__:<module>:148 - Traceback (most recent call last): File "format.py", line 93, in <module>
new_dict = doStepByStepCleanse(row, isChina, line_count) File "format.py", line 43, in doStepByStepCleanse
state = lookup[api_response['Response']['View'][0]['Result'][0]['Location']['Address']['State']] KeyError: '山东省'
Is this possible to achieve?
If you read the error, I'm not sure you've defined all possible keys that the API returns. There's nothing special about the Chinese characters being in the dictionary, just that KeyError: '山东省' means that it really isn't there in your dictionary
If you're not guaranteed to have all known keys ahead of time, you should fallback to getting a default value
lookup.get(api_response['Response']['View'][0]['Result'][0]['Location']['Address']['State']], "Unknown")
Related
I am trying to collect two JSON files into one JSON file but the are completely different, but there are some elements are the same ex: NAME . So I want to get the different elements and add and but them with new Key name and do choose one element from the similar element I mean the Key!
And I tried to do it with this method:
data = json.load(open("file1.json", encoding="utf-8-sig"))
data2 = json.load(open("file2.json", encoding="utf-8-sig"))
for q in data :
for d in data2:
if d["web Name"]== q["Name"]:
ALLDATA.append({
"name": q["Name"],
"rating":q["Rating"],
"addressf1": q["Address"],
"URLf2": d["URL"],
})
break
else:
pass
pass
in name key I choose form which file I will get the value.
but the method give me error:
Traceback (most recent call last):
File "E:/project/PycharmProjects/json work/testing.py", line 63, in <module>
"addressf1": q["Address"],
KeyError: 'Address'
and when I try to print the address in the same loop it print it once and stop .
Thank you John Gordon .
the problem was like what you said on your comment .
Thank to you all .
And i use this code to fill my JSON file with the missing key at every element:
finaldata=[]
data = json.load(open("file1.json", encoding="utf-8-sig"))
for item in data :
if "Address" in item:
finaldata.append(item)
pass
else:
item["Address"]=None
finaldata.append(item)
How do you iterate a array of javax.management.openmbean.CompositeDataSupport?
myBean = ObjectName('com.oracle.sdp.messaging:Location=my_soa_server,name=EmailDriverConfig,type=SDPMessagingDriverConfig,Application=usermessagingdriver-email')
driverParams = mbs.getAttribute(myBean,'DriverParameterProperties')
for param in driverParams:
####How to do iterate and do an if on a name#####
print param.getName()
If I do something like this I am getting..
Traceback (innermost last):
File "<console>", line 1, in ?
AttributeError: getName
I have verified that when you execute driverParams[0] that I am getting something like this
javax.management.openmbean.CompositeDataSupport(compositeType=javax.management.openmbean.CompositeType(name=Property,items=((itemName=allowedValues,itemType=javax.management.openmbean.ArrayType(name=[Ljavax.management.openmbean.CompositeData;,dimension=1,elementType=javax.management.openmbean.CompositeType(name=AllowedValue,items=((itemName=label,itemType=javax.management.openmbean.SimpleType(name=java.lang.String)),(itemName=value,itemType=javax.management.openmbean.SimpleType(name=java.lang.String)))),primitiveArray=false)),(itemName=description,itemType=javax.management.openmbean.SimpleType(name=java.lang.String)),(itemName=encodedCredential,itemType=javax.management.openmbean.SimpleType(name=java.lang.String)),(itemName=mandatory,itemType=javax.management.openmbean.SimpleType(name=java.lang.String)),(itemName=name,itemType=javax.management.openmbean.SimpleType(name=java.lang.String)),(itemName=type,itemType=javax.management.openmbean.SimpleType(name=java.lang.String)),(itemName=value,itemType=javax.management.openmbean.SimpleType(name=java.lang.String)))),contents={allowedValues=[], description=Supported Delivery Types, encodedCredential=false, mandatory=yes, name=SupportedDeliveryTypes, type=java.lang.String, value=EMAIL})
Looking at the attribute, I would like to validate the SupportedDeliveryTypes value
name=SupportedDeliveryTypes
value=EMAIL
description=Supported Delivery Types
CompositeDataSupport is not an array.
To view its content you can try using toString() (in your sample driverParams[0].toString()) or access values with values() or get(String key) / getAll(String[] keys).
For example, try with:
myBean = ObjectName('com.oracle.sdp.messaging:Location=my_soa_server,name=EmailDriverConfig,type=SDPMessagingDriverConfig,Application=usermessagingdriver-email')
driverParams = mbs.getAttribute(myBean,'DriverParameterProperties')
for param in driverParams:
print param.toString()
I'm reading a json file with the structure below:
[{"id":1,"gender":"Male","first_name":"Andrew","last_name":"Scott","email":"ascott0#shutterfly.com","ville":"Connecticut"},
{"id":3,"first_name":"Mary","last_name":"Richards","email":"mrichards2#japanpost.jp","ville":"Minnesota"}]
So, as you can see in the second "line" the field "gender" it'is not present.I realize that because my code to read the file got wrong in this line.
my code:
import json
def jsonreader():
##Reader for json files
##Open files using json library
with open('cust_data.json') as file:
data = json.load(file)
resultlist = list()
for line in data:
print(line["id"],line["gender"])
I got the error:-
C:/xxxxx/x.py
1 Male
Traceback (most recent call last):
2 Female
File "C:/xxxxx/x", line 67, in <module>
jsonreader()
File "C:/xxxxx/x", line 56, in jsonreader
print(line["id"],line["gender"])
KeyError: 'gender'
Before answer guys, you should know that I have a method to define the default value in "gender", voila my method:
def definegender(x):
if x is None:
x = 'unknown'
return x
elif (x =='Male') or (x=='Female'):#not None:
return {
'Male':'M',
'Female': 'F'
}.get(x)
else:
return x
So, in this case, I could not use something like a default value reading the values because I need to send some value to my method.
Some one of you guys would know how should be the best way to read this kind of files when we have missing objects. Thanks
why not using a default value for your dictionary in dict.get?
print(line["id"],line.get("gender","unknown"))
And since you want to transform input further, you could nest two dict.get together, the first one with None as default value, and a new table, like this:
gender_dict = {"Male":"M", "Female":"F", None : "unknown"}
print(line["id"],gender_dict.get(line.get("gender")))
(note that you don't need your overcomplex gender conversion method anymore)
Although this already has a perfect answer, my point of view is that there can be alternatives too. So here it is:
for line in data:
try:
print(line["id"],line["gender"])
except KeyError:
print(line["id"],"Error!!! no gender!")
This is called ErrorHandling. Read the docs here:
https://docs.python.org/3.6/tutorial/errors.html
update: Do you mean this?
update2 corrected misstake
try:
gender = definegender(line["gender"])
except KeyError:
gender = definegender(None)
print(line["id"],gender)
update3: (for future purposes)
as .get() returns None by default the most simple solution would be
gender = definegender(line.get("gender"))
print(line["id"],gender)
Why not simplify this with an if-statement?
for line in data:
if "gender" in line:
print(line)
I'm pretty sure that my error is a very small and stupid thing but I'm not capable to see it!! :(
I have a defined dictionary: self.names_to_nodes, and I want to access to one of its members with the key that I have.
Here is a piece of my code:
print "Result " + str(len( self.names_to_nodes))
if i in self.names_to_nodes:
print "ESTA"
member = self.names_to_nodes.get(i)
ancestrosA.append(member.get_parent())
And I get this exit and this error:
Result 17
ESTA
143 print "ESTA"
144 member = self.names_to_nodes.get(i)
145 ancestrosA.append(member.get_parent())
146 i = member.get_parent()
147 ancestrosA.append(self.founder)
AttributeError: 'NoneType' object has no attribute 'get_parent'
How is this possible???
Thanks for your help! How get(i) is not finding the element if the key is in the dictionary?
BR,
Almu
You need to move the lookup inside the if statement if you want to make sure it exists before checking:
if i in self.names_to_nodes:
print "ESTA"
# only does a lookup if the key exists
member = self.names_to_nodes[i]
ancestrosA.append(member.get_parent())
You check if it exists but still check i outside the if so whether i exists or not you always do a lookup.
dict.get returns a value whether the key is in the dictionary or not. Example:
>>> x = {1:2}
>>> print(x.get(100))
None
Try using regular item access instead. Then your code will raise an exception if you try to get a nonexistent value. Example:
>>> x = {1:2}
>>> print(x[100])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 100
(Readers may ask, "but how could i not be a key in the dictionary? 'ESTA' was printed, and that only occurs when the membership test successfully passes". I'm assuming that this code is inside a for loop that changes the value of i, and the printed 'ESTA' is from the previous iteration, which ran without problems.)
This program is a function that takes dictionary and it must return a new dictionary with mirror image of the original dictionary (meaning key:value pairs are switched).
However, according to pythontutor.com, for the line of code that says the for loop, it throws a RuntimeError.
I am using the latest version of Python (3.4.1)
#Program purpose: Write a function called rvBirthday that takes
# dictionary birthday as input. It returns a
# mirror image of the dictionary, where birthday
# is the key and name is the value.
def rvBirthday(birthday):
reverseBD = {}
for key in birthday.keys():
date = birthday.get(key)
birthday.pop(key)
reverseBD[date] = key
return reverseBD
birthday = {'Mitsuyuki Washida':'3-29-93', 'Joe Bob':'7-12-96',
'Sam Wilson':'4-1-02'}
print(rvBirthday(birthday))
The error I get is:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in rvBirthday
RuntimeError: dictionary changed size during iteration
You are altering the input dictionary while looping over it by using dict.pop(). This changes the dictionary size, and that breaks iteration.
Your instructions say nothing about removing keys from the input dictionary. Remove the dict.pop() calls altogether.
You don't need to use .keys() or .get() here either. Looping over a dictionary yields keys, so you don't have to use a separate method to extract the keys. You then know that those keys are in the dictionary, so .get() to return default if it is missing is also redundant.
Better loop over the dictionary items; this gives you both the key and the value in one step:
def rvBirthday(birthday):
reverseBD = {}
for key, date in birthday.items():
reverseBD[date] = key
return reverseBD
This can be expressed with a dictionary comprehension too:
def rvBirthday(birthday):
return {date: key for key, date in birthday.items()}
If you still need to clear the input dictionary, simply add a birthday.clear() call after copying across the key-value pairs.