Gah, hit the reply button instead of reply-all. :-(<br clear="all"><br>--<br><br>I enjoy haiku<br>but sometimes they don't make sense;<br>refrigerator?<br>
<br><br><div class="gmail_quote">---------- Forwarded message ----------<br>From: <b class="gmail_sendername">Matthew Wood</b> <span dir="ltr"><<a href="mailto:woodm1979@gmail.com">woodm1979@gmail.com</a>></span><br>
Date: Wed, Jun 9, 2010 at 2:30 PM<br>Subject: Re: [Tutor] treeTraversal, nested return?<br>To: <a href="mailto:jjcrump@uw.edu">jjcrump@uw.edu</a><br><br><br>Well, I've taken a look at your code. In your last example, the appending last line here:<div>
<div class="im"><br><div><span style="font-family:arial, sans-serif;font-size:12.5px;border-collapse:collapse">> else:<br>
> for x in getWorks(id):<br>> result.extend(makeNestedLists(x[1]))</span></div><div><br></div></div><div>uses, a list.extend call. If you switch that to append, you SHOULD see the result you're looking for. ...at least as best I can guess without replicating the code and having some good test cases.</div>
<div><br></div><div><br></div><div>Here's some of your other questions:</div><div class="im"><div><br></div><div><span style="font-family:arial, sans-serif;font-size:12.5px;border-collapse:collapse">>To my surprise, I say, because it looks like it shouldn't work at all</span></div>
<div><span style="font-family:arial, sans-serif;font-size:12.5px;border-collapse:collapse">>with the result being set to the empty list with each recursion;</span></div><div><br></div></div><div>
Each time you call the function 'makeNestedLists' a new copy of all the local variables is created. Thus, you aren't blanking the 'result' list each time; instead you're creating a new list each time. Then, when you return the list, you then shove it into the parent-function-instance list.</div>
<div><br></div><div>Just take care to understand the difference between: </div><div><br></div><div>[1, 2, 3].append([4, 5, 6]) -> [1, 2, 3, [4, 5, 6]]</div><div>[1, 2, 3].extend([4, 5, 6]) -> [1, 2, 3, 4, 5, 6]</div>
<div><br></div><div>Your list comprehension example above adds an extra list wrapper around things, which is why the extend worked.</div><div><br></div><div><div class="im"><br clear="all"><br>--<br><br>I enjoy haiku<br>
but sometimes they don't make sense;<br>
refrigerator?<br>
<br><br></div><div><div></div><div class="h5"><div class="gmail_quote">On Wed, Jun 9, 2010 at 12:40 PM, <span dir="ltr"><<a href="mailto:jjcrump@uw.edu" target="_blank">jjcrump@uw.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Thanks to Matthew and Denis for trying to enlighten me. Thanks to your clues I've made some progress; however, I can't seem to get the hang of the usual recursion trick of keeping track of the level one is on. It doesn't work, I suppose, because the data structure I'm traversing isn't actually nested, its a flat series of lists of tuples.<br>
<br>
I did finally get a function to traverse the "tree-like" data coming from the db<br>
<br>
getRecord() returns a tuple of record-type, record-id, parent-id, and title, thus:<br>
('work', 47302, 47301, 'record title')<br>
<br>
getImages(id) returns a list of 'image' tuples whose parent-id is id<br>
getWorks(id) returns a list of 'work' tuples whose parent-id is id<br>
<br>
works can be nodes, images can't<br>
<br>
so:<br>
<br>
def makeDecendentList(id, result):<br>
result.append(getRecord(id))<br>
if getImages(id):<br>
for x in getImages(id):<br>
result.append(x)<br>
if not getWorks(id):<br>
return<br>
else:<br>
for y in getWorks(id):<br>
makeDecendentList(y[1],result)<br>
return result<br>
<br>
called with the empty list as the second argument.<br>
<br>
Well and good. This walks the 'tree' (following the parent-ids) and returns me a list of all the decendents of id. But what I wanted was a nested data structure.<br>
<br>
In the fashion of an ape given a typewriter and sufficient time, I trial and errored my way to this:<br>
<br>
def makeNestedLists(id):<br>
result = []<br>
result.append(getRecord(id))<br>
result.extend(getImages(id))<br>
if not getWorks(id):<br>
return result<br>
else:<br>
result.extend([makeNestedLists(x[1]) for x in getWorks(id)])<br>
return result<br>
<br>
To my surprise, this gets me exactly what I wanted, eg:<br>
<br>
[ ('work', 47301, 47254, 'a title'),<br>
('image', 36871, 47301, 'a title'),<br>
('image', 36872, 47301, 'a title'),<br>
[ ('work', 47302, 47301, 'a title'),<br>
('image', 10706, 47302, 'a title'),<br>
('image', 10725, 47302, 'a title')<br>
]<br>
]<br>
<br>
To my surprise, I say, because it looks like it shouldn't work at all with the result being set to the empty list with each recursion; moreover, if I spell out the loop in the list comp like this:<br>
<br>
def makeNestedLists(id):<br>
result = []<br>
result.append(getRecord(id))<br>
result.extend(getImages(id))<br>
if not getWorks(id):<br>
return result<br>
else:<br>
for x in getWorks(id):<br>
result.extend(makeNestedLists(x[1]))<br>
return result<br>
<br>
I once again get a flat list of all the decendents of id.<br>
<br>
I know it's sad, but can any wise tutor explain to me what's going on in the code that I myself wrote?<br>
<br>
Thanks,<br>
Jon<br>
</blockquote></div><br></div></div></div></div>
</div><br>