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.)
Related
I have a scenario , where I am trying to get index position of value
My code :
a_set = {22,56,26}
print(a_set[56])
Getting below error
Traceback (most recent call last):
File "<string>", line 5, in <module>
TypeError: 'set' object is not subscriptable
Expected output :
1 -> This the position of 56 from set
The error is explaining a lot here: sets in Python are not subscriptable.
They dont have order relation.
According to your code example, you are trying to ask weather a value exists in the set, right?
In Python you can do it with in operator:
>> print(36 in a_set)
True
or
if (36 in a_set):
my_function()
Sets are by definition completely unordered and unindexed, you cannot get the information with an index directly as that is not what they were made for. As a workaround, you can simply convert the set to a list that is both indexed and ordered.
a_set = {22,56,26}
print(list(a_set)[3]) # converts the set into and displays it's third entry.
To solve your problem, you can use .index() on the new list such as this:
a_set = {1,2,3}
print(list(a_set).index(1))
I am trying to write a python script to merge two csv files shown below, the variable 'countries' is a dictionary with about 9 countries and data structure is like this:
{'FR': {'country_destination': 'FR', 'destination_language ': 'fra', 'lng_destination': '2.209667', 'language_levenshtein_distance': '92.06', 'destination_km2': '643801.0', 'distance_km': '7682.945', 'lat_destination': '46.232193'}, 'NL': {'country_destination': 'NL', 'destination_language ': 'nld', 'lng_destination': '5.29525', 'language_levenshtein_distance': '63.22', 'destination_km2': '41543.0', 'distance_km': '7524.3203', 'lat_destination': '52.133057'}
Now this part of code:
else:
correctedRow['destination_language'] = countries[country].get('destination_language', 'NDF')
correctedRow['lng_destination'] = countries[country].get('lng_destination', 'NDF')
correctedRow['language_levanshtien_distance'] = countries[country].get('language_levanshtien_distance', 'NDF')
correctedRow['destination_km2'] = countries[country].get('destination_km2', 'NDF')
is giving me following error:
KeyError Traceback (most recent call last)
<ipython-input-9-f3b0363bcc74> in <module>()
26 correctedRow['lat_destination'] = 'NDF'
27 else:
---> 28 correctedRow['destination_language'] = countries[country].get('destination_language', 'NDF')
29 correctedRow['lng_destination'] = countries[country].get('lng_destination', 'NDF')
30 correctedRow['language_levanshtien_distance'] = countries[country].get('language_levanshtien_distance', 'NDF')
KeyError: 'other'
Typically key error occurs when the key value I'm trying to access in a python dictionary is missing, which is why I used .get(keyvalue, default) in my code. But I do not understand what is happening here. Can anyone explain? and how should I rectify this?
Seems most likely that the error is from looking up countries[country], not the subsequent get call. Psychic debugging says country is "other", and it isn't finding that key in countries.
Your comment asks "The reason why I'm using .get(key, default) is to return default when the key is absent right?" And to that, the answer is, no, you're doing a two stage lookup, first in a dict of dicts, and the second in the resulting dict returned from the first stage. .get is saving you from failure in the second stage of the lookup, but it can't magically save you from failure in the first stage if you don't use it for the first stage.
If the goal is to autovivify a country if it doesn't exist, you can do that by changing countries[country] to countries.get(country, {}) so you use .get at both stages, and the effect of a non-existent country is to get the default values. Or you can use countries.setdefault(country, {}) which acts like get except it will set the key to the default value given before returning it when the key is not present.
For performance (avoiding redundant lookups and redundant default dict construction), you might change the block of code to:
country_data = countries.get(country, {})
correctedRow['destination_language'] = country_data.get('destination_language', 'NDF')
correctedRow['lng_destination'] = country_data.get('lng_destination', 'NDF')
correctedRow['language_levanshtien_distance'] = country_data.get('language_levanshtien_distance', 'NDF')
correctedRow['destination_km2'] = country_data.get('destination_km2', 'NDF')
I am trying to write a targeting priority script for an AI. My goal is to rank targets based on their score of damage_per_shot / rate_of_fire and reorder the list based on highest targeting priority. I finally hit an error I didn't know how to work around however. 'NoneType' object has no attribute 'get'
I am very new to Python and built this mostly by Googling the terms I would have used in Ruby. I would also appreciate suggestions about how to do this in the correct Python "style" if I made any major errors.
enemyList=[{"id":1,"damage_per_shot":10,"rate_of_fire":2},{"id":3,"damage_per_shot":0,"rate_of_fire":0},{"id":2,"damage_per_shot":14,"rate_of_fire":2}]
#enemyList=unit_client.ask_nearest_enemy()
print(enemyList)
aDict = {}
for item in enemyList:
if(item["rate_of_fire"]!=0):
currScore=float(item["damage_per_shot"]/item["rate_of_fire"])
aDict[item['id']] = currScore
def focus_fire2(data=None, *args, **kawargs):
print("===ff2===")
target_id=sorted(aDict, key=data.get)
print(target_id)
print("attacking: "+str(id))
#unit_client.do_attack(key)
##remove item from list
if(len(aDict)>0):
del aDict[target_id] #remove the object from the dict after done
print(aDict)
focus_fire2()
else:
return 0
#unit_client.when_item_destroyed(target, aDict.pop(key,None))
#unit_client.when_item_destroyed(target, focus_fire2)
focus_fire2()
The traceback looks like
[{'damage_per_shot': 10, 'id': 1, 'rate_of_fire': 2}, {'damage_per_shot': 0, 'id
': 3, 'rate_of_fire': 0}, {'damage_per_shot': 14, 'id': 2, 'rate_of_fire': 2}]
===ff2===
Traceback (most recent call last):
File "ffire.py", line 26, in <module>
focus_fire2()
File "ffire.py", line 13, in focus_fire2
target_id=sorted(aDict, key=data.get)
AttributeError: 'NoneType' object has no attribute 'get'
Just replace
sorted(aDict, key=data.get)
by
sorted(aDict, key=aDict.get)
In your function focus_fire2, you set data to None by default in the arguments of the function definition. Unless you set it to something other than None when you call it, like focus_fire2(data=something), then it's equal to None when you do, data.get() later on. And there lies your error I think. You are treating a NoneType like a dict. If you're calling get on it, you probably should be setting it equal to some dict or other.
You get an error, because run function without arguments, and by default data have a None type. And for me it's not good idea, set default value as None for non optional arguments. You need run function with argument focus_fire2(aDict), or change target_id=sorted(aDict, key=data.get) to target_id=sorted(aDict, key=aDict.get, reverse=True) you get in target_id, list of sorted key from aDict, where first value is higher. But target_id is a list and this code is wrong del aDict[target_id]. What must be in target_id?
This is the simplest of exercises. I just don't understand why it wont work.
Here's my code:
hobbies = []
for i in range(3):
hobby = raw_input("Name a hobby")
hobbies = hobbies.append(hobby)
Basically I want to ask my user 3 times to name one of his hobbies, and store them in a list. But for some reason I'm getting this error,
Traceback (most recent call last):
File "C:/Python27/hobbies.py", line 4, in <module>
hobbies = hobbies.append(hobby)
AttributeError: 'NoneType' object has no attribute 'append'
which I don't really understand.
The problem is that append() will change the list in-place. And when you call this function no value is returned.
The first time you get a None value for the variable hobbies. The second time you try to call the append() method for a None value...
You should not use hobbies = hobbies.append(). Instead use hobbies.append() only.
I need to add a key with a value that increases by one for every item in the nested dictionary. I have been trying to use the dict['key']='value' syntax but can't get it to work for a nested dictionary. I'm sure it's a very simple.
My Dictionary:
mydict={'a':{'result':[{'key1':'value1','key2':'value2'},
{'key1':'value3','key2':'value4'}]}}
This is the code that will add the key to the main part of the dictionary:
for x in range(len(mydict)):
number = 1+x
str(number)
mydict[d'index']=number
print mydict
#out: {d'index':d'1',d'a'{d'result':[...]}}
I want to add the new key and value to the small dictionaries inside the square parentheses:
{'a':{'result':[{'key1':'value1',...,'index':'number'}]}}
If I try adding more layers to the last line of the for loop I get a traceback error:
Traceback (most recent call last):
File "C:\Python27\program.py", line 34, in <module>
main()
File "C:\Python27\program.py", line 23, in main
mydict['a']['result']['index']=number
TypeError: list indices must be integers, not unicode
I've tried various different ways of listing the nested items but no joy. Can anyone help me out here?
The problem is that mydict is not simply a collection of nested dictionaries. It contains a list as well. Breaking up the definition helps clarify the internal structure:
dictlist = [{'key1':'value1','key2':'value2'},
{'key1':'value3','key2':'value4'}]
resultdict = {'result':dictlist}
mydict = {'a':resultdict}
So to access the innermost values, we have to do this. Working backwards:
mydict['a']
returns resultdict. Then this:
mydict['a']['result']
returns dictlist. Then this:
mydict['a']['result'][0]
returns the first item in dictlist. Finally, this:
mydict['a']['result'][0]['key1']
returns 'value1'
So now you just have to amend your for loop to iterate correctly over mydict. There are probably better ways, but here's a first approach:
for inner_dict in mydict['a']['result']: # remember that this returns `dictlist`
for key in inner_dict:
do_something(inner_dict, key)
I'm not fully sure what you're trying to do, but I think itertools.count would be able to help here.
>>> c = itertools.count()
>>> c.next()
0
>>> c.next()
1
>>> c.next()
2
>>> c.next()
3
... and so on.
Using this, you can keep incrementing the value that you want to use in your dicts
Hope this helps