Let's make it a bit easier.
Code:
level3 = {'a':'aa'}
level2 = {'b':level3, 'd':level3}
level1 = {'j':level2, 'k':level2}
def print_rec(node = None):
if node is None:
node = level1
if node == 'aa':
return
for key, successor in node.items():
print(key,":",node.get(key))
print_rec(successor)
print_rec()
Outputs:
k : {'d': {'a': 'aa'}, 'b': {'a': 'aa'}}
d : {'a': 'aa'}
a : aa
b : None
Traceback (most recent call last):
File "test.py", line 13, in <module>
print_rec(level1)
File "test.py", line 11, in print_rec
print_rec(node)
File "test.py", line 11, in print_rec
print_rec(node)
File "test.py", line 8, in print_rec
for key in node:
TypeError: 'NoneType' object is not iterable
I think node = node.get(key) will be executed only if the key is in node. So why the new node will get a NoneType? Anyone can help?
In the for loop, it seems like you're using the name node for two different things:
for key in node:
print(key,":",node.get(key))
node = node.get(key)
print_rec(node)
When in the first iteration, you change the value of node. In the second iteration, when you do node.get(key), you're using the new node, but you want to be using the original node.
This should help:
for key in node:
print(key,":",node.get(key))
successor = node.get(key)
print_rec(successor)
It can be written even more concisely like this:
for key, successor in node.items():
print(key,":",successor)
print_rec(successor)
Related
I was running python code below:
def dict2struct(d):
res = namedtuple("config", d.keys())(*d.values())
return res
cfg = {'fieldx': 'Allan', "fieldy": 45, 'fieldt': {'head': False, 'number': 2}}
res = dict2struct(cfg)
print(res)
res.fieldx = "Jack"
and got the error:
config(fieldx='Allan', fieldy=45, fieldt={'head': False, 'number': 2})
Traceback (most recent call last):
File "*****\Testings\test_x.py", line 97, in <module>
res.fieldx = "Jack"
AttributeError: can't set attribute
I have read the questions below and understand that it was because namedtuples are immutable and the property setter was restricted.
AttributeError: can't set attribute
AttributeError: can't set attribute in python
However, I need to convert a lot of strings from a configurational dictionary's keys to properties of a struct or a class. These strings values are not fixed as they are many.
Is there a way to get around of this AttributeError for my problem?
Steve's solution above worked for me.
pypi.org/project/attributedict
i have a nested dictionary in the form of:
self.emoji_per_word = {0: {'worte': 0, 'emojis': 0, '#': 0}}
Now i need to add more sub dictionaries to this as my program runs. I do this:
worte = 0
emoji = 0
# some code that assigns values to the 2 variables and creates the time_stamp variable
if time_stamp in self.emoji_per_word:
self.emoji_per_word[time_stamp]['worte'] = self.emoji_per_word[time_stamp]['worte'] + worte
self.emoji_per_word[time_stamp]['emojis'] = self.emoji_per_word[time_stamp]['emojis'] + emojis
else:
self.emoji_per_word[time_stamp]['worte'] = worte
self.emoji_per_word[time_stamp]['emojis'] = emojis
As you can see, i try to the test if the key time_stamp already exists and if yes, update the value with the new data. If not i want to create the key time_stamp and assign it a inital value. However im getting a Key Error once the programm goes past the inital value (see top).
Exception in thread Video 1:
Traceback (most recent call last):
File "C:\Anaconda\lib\threading.py", line 916, in _bootstrap_inner
self.run()
File "C:\MA\Code\jsonparser_v2\jsonparser_v2.py", line 418, in run
self.process_json()
File "C:\MA\Code\jsonparser_v2\jsonparser_v2.py", line 201, in process_json
self.emoji_per_word[time_stamp]['worte'] = worte
KeyError: 1
What I want in the end is something like this:
self.emoji_per_word = {0: {'worte': 20, 'emojis': 5, '#':0.25}, 1: {'worte': 20, 'emojis': 5, '#':0.25}}
What am I doing wrong here?
You're getting the error because self.emoji_per_word[time_stamp] doesn't exist when time_stamp != 0 so you need to create the dictionary first before assigning values to it, like so:
else:
self.emoji_per_word[time_stamp] = {}
self.emoji_per_word[time_stamp]['worte'] = worte
self.emoji_per_word[time_stamp]['emojis'] = emojis
I got an error,TypeError: 'int' object is not subscriptable .
I wanna connect 2 excel data
to User model.
So my ideal output is
1|1|Blear|40|false|l|America|A|1
2|5|Tom|23|true|o|UK|A|3
3|9|Rose|52|false|m
4|10|Karen||||Singapore|C|2
For example,Rose data of user_id=3 is not in second excel, in that case being 2nd data empty is ok.I am thinking putting 2nd excel in dictionary type to User model.
I searched the errors I thought this part for data in data_dict was wrong, I changed it into for data in range(len(data_dict)) but same error happens.I really cannot understand where is wrong.How should I fix this?
Now views.py is
#coding:utf-8
from django.shortcuts import render
import xlrd
from .models import User
book = xlrd.open_workbook('../data/excel1.xlsx')
sheet = book.sheet_by_index(1)
def build_employee(employee):
if employee == 'leader':
return 'l'
if employee == 'manager':
return 'm'
if employee == 'others':
return 'o'
for row_index in range(sheet.nrows):
rows = sheet.row_values(row_index)
is_man = rows[4] != ""
emp = build_employee(rows[5])
user = User(user_id=rows[1], name_id=rows[2], name=rows[3],
age=rows[4],man=is_man,employee=emp)
user.save()
book2 = xlrd.open_workbook('../data/excel2.xlsx')
sheet2 = book2.sheet_by_index(0)
headers = sheet2.row_values(0)
large_item = None
data_dict = {}
for row_index in range(sheet2.nrows):
rows2 = sheet2.row_values(row_index)
large_item = rows2[1] or large_item
# Create dict with headers and row values
row_data = {}
for idx_col, value in enumerate(rows2):
header_value = headers[idx_col]
# Avoid to add empty column. A column in your example
if header_value:
row_data[headers[idx_col]] = value
# Add row_data to your data_dict with
data_dict[row_index] = row_data
for row_number, row_data in data_dict.items():
user1 = User.objects.filter(user_id = data['user_id']).exists()
if user1:
user1.__dict__.update(**data_dict)
user1.save()
Now Traceback is
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/XXX/testapp/app/views.py", line 123, in <module>
user1 = User.objects.filter(user_id = row_data['user_id']).exists()
KeyError: 'user_id'
data is an integer. So calling data like a dict raises that expection.
>>> a=1
>>> a['a']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not subscriptable
Why is it an int ? Because you're iterating over data's keys:
>>> a={1: 'x', 2: 'c'}
>>> for i in a: print(i)
...
1
2
Try using items() as such:
>>> for key, value in a.items(): print(key, value)
...
1 x
2 c
Or, in your specific case:
for row_number, row_data in data_dict.items():
print(row_number, row_data)
See looping techniques for dict documentation for details.
I'm trying to create multiple graph and using Dijkstra's. However I'm getting an error: NoneType object has no attribute 'set_distance'. The very strange thing is that the first item in the list ['2001A1'] runs fine but then when the list is longer than 1 it just crashes with that error. If I run the code with just one item in the list, it works as well. Printing out my vertices, the graph shows that there are vertex instances for all of my keys... Is there something that I'm missing? Why can't I do this more than one times? Why is it that when I try to get my vertex object I get returned null when my map of vertices has key {1:(Vertex object)}?
def create_graph(q,y,pop,psub,a,b,c):
a = Graph(q,y,pop,psub,a,b,c)
for i in range(0,9):
a.add_vertex(i)
return a
def run_dijkstras(graph,data):
for i in data:
try:
year = int(i[0:4])
print year
except:
print i
rest = i[4:]
graph.add_edge(year,rest)
quarter = graph.get_quarter()
print graph.vert_dict
print quarter
print graph.get_vertex(quarter)
print str(graph.get_vertex(quarter))
dijkstra(graph,graph.get_vertex(quarter))
target = graph.get_vertex(quarter+4)
path = [target.get_id()]
shortest(target, path)
if len(path) == 1:
path = "NULL"
return [path,(str(target.get_distance())),data]
i = 2001
for j in range(1,5):
for datacombo in ([['2001A1'], ['2001R4']]):
a = run_dijkstras(create_graph(j,i,10,1,.05,-.1,-.5),datacombo)
result,score = a[0],a[1]
if score == 9999999999999:
score = "NULL"
score = score.ljust(15)
datacombo = generate_matrix(datacombo)
i = str(i).ljust(5)
j = str(j).ljust(2)
datacombo=re.sub("\[|\]|'","",str(datacombo)).ljust(100)
result=re.sub("\[|\]|'","",str(result)).ljust(25)
print(i,j,result,score,datacombo)
ERROR LOG:
{0: <__main__.Vertex instance at 0x0000000002439DC8>, 1: <__main__.Vertex instan
ce at 0x0000000002439CC8>, 2: <__main__.Vertex instance at 0x0000000002439C88>,
3: <__main__.Vertex instance at 0x0000000002439C08>, 4: <__main__.Vertex instanc
e at 0x0000000002439E48>, 5: <__main__.Vertex instance at 0x0000000002439E88>, 6
: <__main__.Vertex instance at 0x0000000002439EC8>, 7: <__main__.Vertex instance
at 0x0000000002439F08>, 8: <__main__.Vertex instance at 0x0000000002439F48>}
1
None
None
Traceback (most recent call last):
File "dijkstras3.py", line 282, in <module>
a = run_dijkstras(create_graph(j,i,10,1,.05,-.1,-.5),datacombo)
File "dijkstras3.py", line 190, in run_dijkstras
dijkstra(graph,graph.get_vertex(quarter))
File "dijkstras3.py", line 132, in dijkstra
start.set_distance(0)
AttributeError: 'NoneType' object has no attribute 'set_distance'
I'm testing the following function:
def getDataMapOfFirstLine(line):
datamap = {}
for item in line:
hierarchy = item.split('^')
partialmap = datamap
i=0
for node in hierarchy:
partialmap = partialmap.setdefault(node, i)
i += 1
return datamap
It should create a dictionary out of the first line of a csv-file, that looks like this:
nummer;such;ans;bverb^konum;bverb^namebspr;bverb^bank^iident;
1213;HANS;Hans Dominik;111000222;Hans' account; DE2145432523534232;
1444555;DIRK;Dirk Daniel;13300002;Dirk's account; DE2134634565462352;
As you see these circumflex-signs in each semicolon-separated string are something like a join in SQL. If I execute it, I get this error:
Traceback (most recent call last):
File "./importtool.py", line 173, in <module>
main()
File "./importtool.py", line 38, in main
analyseImportFile(importfile, parser, options)
File "./importtool.py", line 119, in analyseImportFile
datamap = getDataMapOfFirstLine(line)
File "./importtool.py", line 149, in getDataMapOfFirstLine
partialmap = partialmap.setdefault(node, i)
AttributeError: 'int' object has no attribute 'setdefault'
If I replace the i in the setdefault-function by {} I get no error:
{'bverb': {'namebspr': {}, 'konum': {}, 'bank': {'iident': {}}}, 'such': {}, 'ans': {}}
This is nearly, what I want, but instead of the {} I would like to get a column-number.
I just don't get what is wrong. I tried this in interactive mode:
>>> mydict = {'foo': "Hallo", 'bar': 5}
>>> mydict.setdefault("sth", 12)
12
>>> print mydict
{'sth': 12, 'foo': 'Hallo', 'bar': 5}
As you see, this works...
I appreciate every help. Thanks in advance!
Your problem is this line:
partialmap = partialmap.setdefault(node, i)
dict.setdefault returns the thing that was set (or what was already there). In this case, it's an integer so you're setting partialmap to an int. You can probably just not grab the return value (which is what you've done in the interactive terminal BTW):
partialmap.setdefault(node, i)