This may be an artifact of for .. in .. yield vs a yield from. I don't have
too much experience with the visualizer (I usually use pdb to step through
code if I need to).

yield from is the "correct" way to call a generator from another generator
and yield the other generators results. (but it only works on Python 3),
and it does a better job of traversing the call-stack.

PEP 380 (http://www.python.org/dev/peps/pep-0380/) has decent information
on yield from, though it's a bit technical.

For a Trie or any Tree, traversing would have to be done this way or
perhaps with visitor/walker pattern. as in trie.walk(lambda node:
print(node)), but that isn't very Pythonic.

Look up tree traversals (pre-order, post-order, in-order, etc.), they all
use recursion somehow.


On Tue, Sep 3, 2013 at 11:41 PM, Maria McKinley <mar...@mariakathryn.net>wrote:

> So, when I look at this code with the visualizer, it looks like the code
> is essentially re-creating the call stack every time through. Looking at
> the code structure, this sort of makes sense to me, since I think recursion
> with a generator means you are essentially creating a new generator every
> time through, so you are yielding to more and more generators each time
> through. But, it seems crazy. I thought the whole point of generators is
> that they remember where they were, so why is the whole stack being
> re-created every time? Or have I just totally mis-understood what is going
> on with the visualizer and/or the generator? Is there a better way to
> traverse the Trie? I did end up with this code by a strange route, so maybe
> the code is sub-optimal.
>
> thanks for being patient with me,
> Maria
>
>
>
> On Sat, Aug 31, 2013 at 12:35 AM, Maria McKinley 
> <mar...@mariakathryn.net>wrote:
>
>> Wow, okay, so that is a lot of recursion and generation for me to wrap my
>> brain around.
>>
>> I was trying to understand what was going on, and I put the code in a
>> visualizer, which you can see here:
>>
>> *http://tinyurl.com/orzrlh2*
>>
>> So, now I can almost wrap my brain around it.
>>
>>
>> On Fri, Aug 30, 2013 at 11:18 PM, Maria McKinley <mar...@mariakathryn.net
>> > wrote:
>>
>>> Yay! Thanks. Still working out exactly how to make it work how I want,
>>> but I feel like I'm getting the idea of how this is working now...  I will
>>> post code when I have it working properly.
>>>
>>> ~maria
>>>
>>>
>>> On Fri, Aug 30, 2013 at 10:42 PM, Mark Harviston <
>>> mark.harvis...@gmail.com> wrote:
>>>
>>>> on line 94 you have
>>>>
>>>>
>>>>
>>>>                 yield node.items()
>>>>
>>>>
>>>> this will yield node.items() which is itself a generator.... this is
>>>> not what you want to do.
>>>>
>>>> If it was Python 3, you could do:
>>>>
>>>>                 yield from node.items()
>>>>
>>>>
>>>>
>>>> and that would be correct.
>>>>
>>>> Since it's Python 2, you have to do
>>>>
>>>>     for i in node.items():
>>>>         yield i
>>>>
>>>> This will make the recursion work and iterate over the whole list.
>>>>
>>>> --Mark
>>>>
>>>>
>>>> On Fri, Aug 30, 2013 at 10:04 PM, Maria McKinley <
>>>> mar...@mariakathryn.net> wrote:
>>>>
>>>>> I'll assume as long as people are answering me, there is enough
>>>>> interest to keep going...
>>>>>
>>>>> I was having a problem seeing the representation of my object, but I
>>>>> did figure that out. I was able to print from the items method, and see
>>>>> that the code wasn't yielding the correct variable in order see the letter
>>>>> itself.
>>>>>
>>>>> Each time you add a word to the trie, it adds each letter of that word
>>>>> to a node. I have two words (that start with different letters) in my 
>>>>> trie,
>>>>> so when I do the loop, I see the two letters at the top node.
>>>>>
>>>>> Weirdly, if I stick in letter.next() in the loop:
>>>>>
>>>>> for letters in mytrie.items():
>>>>>     print 'letters', letters
>>>>>     letters.next()
>>>>>
>>>>> I do get the 2nd layer, but no more. If I try to do more, I get
>>>>> StopIteration. My biggest problem is I can't decide if the problem is my
>>>>> lack of understanding of generators or if this code is just not written
>>>>> correctly. Surely, it is suppose to be iterating through the entire tree,
>>>>> and not just the root level? How do I drill down to lower levels? I see 
>>>>> how
>>>>> it is done for adding new words, but can't make something similar work for
>>>>> looking at unknown words.
>>>>>
>>>>> I have my code up here:
>>>>>
>>>>> https://github.com/codedragon/trie
>>>>>
>>>>> but it isn't a whole lot different from what is in the wikipedia
>>>>> article. Just has a script for playing around with it and some print
>>>>> statements stuck in.
>>>>>
>>>>> thanks again,
>>>>> Maria
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> On Thu, Aug 29, 2013 at 9:49 PM, Joseph Wright <jos...@mammalia.net>wrote:
>>>>>
>>>>>> No, it wouldn't help with the iteration, but I thought you were
>>>>>> having a problem seeing the representation of your object. Now I'm trying
>>>>>> to figure this thing out….
>>>>>>
>>>>>> It looks like the reason the 'char' only showing the first letter is
>>>>>> because in the add() method, the first letter of the string is what it
>>>>>> assigns to head:
>>>>>>
>>>>>>          head, tail = s[0], s[1:]
>>>>>>
>>>>>> So it uses just one letter at a time per node.
>>>>>>
>>>>>> Joseph
>>>>>>
>>>>>>
>>>>>> On Aug 29, 2013, at 8:55 PM, Maria McKinley <mar...@mariakathryn.net>
>>>>>> wrote:
>>>>>>
>>>>>> Not yet, would that solve the problem that it is not iterating? Using
>>>>>> some good old-fashioned print statements, I found out a little bit more.
>>>>>>
>>>>>> I added the following print statements:
>>>>>>
>>>>>>         for char, node in self.root.iteritems():
>>>>>>             # node.value is none when not at end of word
>>>>>>
>>>>>>             if node.value is None:
>>>>>>                 print 'none'
>>>>>>                 print 'char',char
>>>>>>                 print 'node',node
>>>>>>                 yield node.items()
>>>>>>             else:
>>>>>>                 print 'stuff'
>>>>>>                 yield node
>>>>>>
>>>>>> And this was the output. There are 2 words in the trie, but it only
>>>>>> reports the first letter of each word, and stops:
>>>>>>
>>>>>> none
>>>>>> char p
>>>>>> node <trie.Trie instance at 0x10e8d0560>
>>>>>> <generator object items at 0x10e8bc690>
>>>>>> none
>>>>>> char t
>>>>>> node <trie.Trie instance at 0x10e8bab48>
>>>>>> <generator object items at 0x10e8bc5a0>
>>>>>>
>>>>>> ~maria
>>>>>>
>>>>>>
>>>>>> On Thu, Aug 29, 2013 at 7:59 PM, Joseph Wright 
>>>>>> <jos...@mammalia.net>wrote:
>>>>>>
>>>>>>> Have you tried defining __repr__?
>>>>>>>
>>>>>>> Joseph
>>>>>>>
>>>>>>> On Aug 29, 2013, at 7:56 PM, Maria McKinley <mar...@mariakathryn.net>
>>>>>>> wrote:
>>>>>>>
>>>>>>> Thanks Morris. That does answer one question, I can't assume code on
>>>>>>> wikipedia is bug-free. Changing it doesn't solve the problem,
>>>>>>> unfortunately, but you are right, time to hit the debugger. Thanks 
>>>>>>> everyone.
>>>>>>>
>>>>>>> cheers,
>>>>>>> Maria
>>>>>>>
>>>>>>>
>>>>>>> On Thu, Aug 29, 2013 at 5:46 PM, Morris Bernstein <
>>>>>>> mor...@systems-deployment.com> wrote:
>>>>>>>
>>>>>>>> I hate to suggest this because I almost never use it, but have you
>>>>>>>> considered using the pdb debugger and setting a breakpoint?
>>>>>>>>
>>>>>>>> Meanwhile, your problem is here:
>>>>>>>> def items(self):
>>>>>>>>         """Return an iterator over the items of the `Trie`."""
>>>>>>>>         for char, node in self.root.iteritems():
>>>>>>>>             if node.value is None:
>>>>>>>>                 yield node.items
>>>>>>>>
>>>>>>>> node.items is the the Trie.items() method bound to the node object.
>>>>>>>>
>>>>>>>> I think, taking a quick look at the code, you want to yield
>>>>>>>> node.items(), function call again.  Looks like the same problem.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Thu, Aug 29, 2013 at 5:17 PM, Maria McKinley <
>>>>>>>> mar...@mariakathryn.net> wrote:
>>>>>>>>
>>>>>>>>> Doh. Thanks. This does the trick, but it gives me the instance
>>>>>>>>> location. I assumed this is because there is no __str__ method 
>>>>>>>>> defined, but
>>>>>>>>> when I added a __str__ method it didn't change anything. Probably 
>>>>>>>>> didn't
>>>>>>>>> implement the __str__ method correctly, but since I didn't even get an
>>>>>>>>> error, not sure this was even the problem. (Pretty sure, for example, 
>>>>>>>>> that
>>>>>>>>> I shouldn't always be referencing the head node.)
>>>>>>>>>
>>>>>>>>> def __str__(self):
>>>>>>>>>     return "Node letter is %s" % (self.root[0])
>>>>>>>>>
>>>>>>>>> for c in mytrie.items():
>>>>>>>>>     print c
>>>>>>>>>    ...:
>>>>>>>>> <bound method Trie.items of <trie.Trie instance at 0x1010dc710>>
>>>>>>>>> <bound method Trie.items of <trie.Trie instance at 0x1010dca70>>
>>>>>>>>>
>>>>>>>>> thanks again,
>>>>>>>>> Maria
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Thu, Aug 29, 2013 at 4:40 PM, Cris Ewing <c...@crisewing.com>wrote:
>>>>>>>>>
>>>>>>>>>> I expect that the problem here is that you are attempting to
>>>>>>>>>> iterate over the method itself, rather than its result.  You'd need 
>>>>>>>>>> to call
>>>>>>>>>> the method to do that:
>>>>>>>>>>
>>>>>>>>>>   for c in mytrie.items():
>>>>>>>>>>       print c
>>>>>>>>>>
>>>>>>>>>> hth
>>>>>>>>>>
>>>>>>>>>> c
>>>>>>>>>>
>>>>>>>>>> On Aug 29, 2013, at 4:38 PM, Maria McKinley wrote:
>>>>>>>>>>
>>>>>>>>>> Hello,
>>>>>>>>>>
>>>>>>>>>> I hope someone on this list doesn't mind answering what I think
>>>>>>>>>> is a quick question. I have been playing around with the python code 
>>>>>>>>>> found
>>>>>>>>>> here:
>>>>>>>>>>
>>>>>>>>>> http://en.wikipedia.org/wiki/Trie#A_Python_version
>>>>>>>>>>
>>>>>>>>>> I can't get the iterator to work, and I wonder if I'm not calling
>>>>>>>>>> it correctly. I thought once I made my object, and added stuff to 
>>>>>>>>>> it, I
>>>>>>>>>> could just do this:
>>>>>>>>>>
>>>>>>>>>> for c in mytrie.items:
>>>>>>>>>>     print c
>>>>>>>>>>
>>>>>>>>>> but I get this error:
>>>>>>>>>>
>>>>>>>>>> TypeError: 'instancemethod' object is not iterable
>>>>>>>>>>
>>>>>>>>>> What am I doing wrong?
>>>>>>>>>>
>>>>>>>>>> thanks,
>>>>>>>>>> Maria
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>  Cris Ewing
>>>>>>>>>> --------------------------------------------------
>>>>>>>>>> Principal, Cris Ewing, Developer LLC
>>>>>>>>>> http://www.crisewing.com
>>>>>>>>>> c...@crisewing.com
>>>>>>>>>> 1.206.724.2112
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Maria Mckinley
>>>>>>>>> Software Developer with Bonus SysAdmin Experience
>>>>>>>>> www.mariakathryn.net
>>>>>>>>> www.linkedin.com/in/mariamckinley
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Maria Mckinley
>>>>>>> Software Developer with Bonus SysAdmin Experience
>>>>>>> www.mariakathryn.net
>>>>>>> www.linkedin.com/in/mariamckinley
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Maria Mckinley
>>>>>> Software Developer with Bonus SysAdmin Experience
>>>>>> www.mariakathryn.net
>>>>>> www.linkedin.com/in/mariamckinley
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Maria Mckinley
>>>>> Software Developer with Bonus SysAdmin Experience
>>>>> www.mariakathryn.net
>>>>> www.linkedin.com/in/mariamckinley
>>>>>
>>>>
>>>>
>>>
>>>
>>> --
>>> Maria Mckinley
>>> Software Developer with Bonus SysAdmin Experience
>>> www.mariakathryn.net
>>> www.linkedin.com/in/mariamckinley
>>>
>>
>>
>>
>> --
>> Maria Mckinley
>> Software Developer with Bonus SysAdmin Experience
>> www.mariakathryn.net
>> www.linkedin.com/in/mariamckinley
>>
>
>
>
> --
> Maria Mckinley
> Software Developer with Bonus SysAdmin Experience
> www.mariakathryn.net
> www.linkedin.com/in/mariamckinley
>

Reply via email to