Python: what's the pythonic way to perform this loop?

What is the pythonic way to perform this loop. I'm trying to pick a random key that will return a subtree and not the root. Hence: 'parent == None' cannot be true. Nor can 'isRoot==True' be true.

thekey = random.choice(tree.thedict.keys()) while (tree.thedict[thekey].parent == None)or(tree.thedict[thekey].isRoot == True): thekey = random.choice(tree.thedict.keys()) .......

edit: it works now

-------------Problems Reply------------

key = random.choice([key for key, subtree in tree.thedict.items()
if subtree.parent and not subtree.isRoot])

(Corrected after comments and question edition)

get a random subtree that is not the root

not_root_nodes = [key, node for key,node in tree.thedict.iteritems() if not ( node.parent is None or node.isRoot)]
item = random.choice( not_root_nodes )

I think that's a bit better:

theDict = tree.thedict

def getKey():
return random.choice(theDict.keys())

theKey = getKey()

while theDict[thekey].parent in (None, True):
thekey = getKey()

What do you think?

thekey = random.choice(tree.thedict.keys())
parent = thedict[thekey].parent
while parent is None or parent.isRoot:
thekey = random.choice(tree.thedict.keys())
parent = thedict[thekey].parent

thekey = random.choice(tree.thedict.keys())
parent = tree.thedict[thekey].parent
while parent is None or tree.thedict[thekey].isRoot:
thekey = random.choice(tree.thedict.keys())
parent = thedict[thekey].parent

I think your while condition is flawed:

I think you expect this: tree.thedict[thekey].parent == None
should be equal to this: tree.thedict[thekey].parent.isRoot == True

When in fact, for both to mean "this node is not the root", you should change the second statement to: tree.thedict[thekey].isRoot == True

As written, your conditional test says "while this node is the root OR this node's parent is the root". If your tree structure is a single root node with many leaf nodes, you should expect an infinite loop in this case.

Here's a rewrite:

thekey = random.choice(k for k in tree.thedict.keys() if not k.isRoot)

def is_root(v):
assert (v.parent != None) == (v.isRoot)
return v.isRoot
#note how dumb this function looks when you guarantee that assertion

def get_random_nonroot_key():
while True:
thekey = random.choice(tree.thedict.keys())
value = tree.thedict[thekey]
if not is_root(value): return key

or a refactoring of Roberto Bonvallet's answer

def get_random_nonroot_key():
eligible_keys = [k for k, v in tree.thedict.items() if not is_root(v)]
return random.choice(eligible_keys)

Personally, I don't like the repetition of initializing thekey before the while loop and then again inside the loop. It's a possible source of bugs; what happens if someone edits one of the two initializations and forgets to edit the other? Even if that never happens, anyone reading the code needs to check carefully to make sure both initializations match perfectly.

I would write it like so:

while True:
thekey = random.choice(tree.thedict.keys())
subtree = tree.thedict[thekey]
if subtree.parent is not None and not subtree.isRoot:

P.S. If you really just want the subtree, and don't care about the key needed to lookup the subtree, you could even do this:

while True:
subtree = random.choice(tree.thedict.values())
if subtree.parent is not None and not subtree.isRoot:

Some people may not like the use of "while True:" but that is the standard Python idiom for "loop forever until something runs break". IMHO this is simple, clear, idiomatic Python.

P.P.S. This code should really be wrapped in an if statement that checks that the tree has more than one node. If the tree only has a root node, this code would loop forever.

Category:python Views:1 Time:2009-09-11
Tags: python

Related post

  • Performance: Python 3.x vs Python 2.x 2008-10-04

    On a question of just performance, how does Python 3 compare to Python 2.x? --------------Solutions------------- 3.0 is slower than 2.5 on official benchmarks. From "What’s New in Python 3.0": The net result of the 3.0 generalizations is that Python

  • Switching from python-mode.el to python.el 2008-12-12

    I recently tried switching from using python-mode.el to python.el for editing python files in emacs, found the experience a little alien and unproductive, and scurried back. I've been using python-mode.el for something like ten years, so perhaps I'm

  • How do I use my standard python path when running python scripts from xcode macros 2008-12-13

    I'm trying to run Python scripts using Xcode's User Scripts menu. The issue I'm having is that my usual os.sys.path (taken from ~/.profile) does not seem to be imported when running scripts from XCode the way it is when running them at the Terminal (

  • Python 2.5 to Python 2.2 converter 2009-02-23

    I am working on a PyS60 application for S60 2nd Edition devices. I have coded my application logic in Python 2.5. Is there any tool that automates th conversion from Python 2.5 to Python 2.2 or do I need to do in manually? --------------Solutions----

  • Migrating from python 2.4 to python 2.6 2009-05-27

    I'm migrating a legacy codebase at work from python 2.4 to python 2.6. This is being done as part of a push to remove the 'legacy' tag and make a maintainable, extensible foundation for active development, so I'm getting a chance to "do things right"

  • Reloading a changed python file in emacs python shell 2009-11-29

    In the emacs Python shell (I'm running 2.* Python) I am importing a .py file I'm working with and testing the code. If I change the code however I'm not sure how to import it again. From my reading so far it seems that reload(modulename) should work,

  • How to create an application which embeds and runs Python code without local Python installation? 2010-03-22

    Hello fellow software developers. I want to distribute a C program which is scriptable by embedding the Python interpreter. The C program uses Py_Initialize, PyImport_Import and so on to accomplish Python embedding. I'm looking for a solution where I

  • Python 2 vs. Python 3 - urllib formats 2010-06-27

    I'm getting really tired of trying to figure out why this code works in Python 2 and not in Python 3. I'm just trying to grab a page of json and then parse it. Here's the code in Python 2: import urllib, json response = urllib.urlopen("http://reddit.

  • Python threads in embedded Python: How? 2010-07-01

    While experimenting with Python's ( C API, I found myself wondering how to properly spawn threads via Python's threading package when Python itself is embedded in a C program. Functions PyEval_EvalCode and kin appear to terminate threads i

  • Run a python script from another python script, passing in args 2010-09-23

    This question already has an answer here: What is the best way to call a python script from another python script? 7 answers I want to run a python script from another python script. I want to pass variables like I would using the command line. For e

  • How to install both Python 2.x and Python 3.x in Windows 7 2010-09-28

    I do most of my programming in Python 3.x on Windows 7, but now I need to use the Python Imaging Library (PIL), ImageMagick, and wxPython, all of which require Python 2.x. Can I have both Python 2.x and Python 3.x installed in Windows 7? When I run a

  • Embedding Python in C++ - Running Python from C++ program 2010-11-28

    thank you both for a quick response :) i think i understood what you suggest but it is not exactly what i need. To be honest i don't know what is the right technique to do what i need. I have a program which during it's run sometimes needs to call py

  • how to implement unittest.skip from python 3.1 in python 2.6? 2010-12-06

    do you know of any implementation of unittest.skip of python 3.1 in python 2.6/2.7? thanks --------------Solutions------------- Try installing the unittest2 package

  • BufferedReader in Python 2.x vs Python 3.x 2010-12-25

    I have a program that runs in Python 2 and Python 3, but there is a drastic difference in speed. I understand a number of internal changes were made in the switch, but the difference in io.BufferedReader are really high. In both versions, I use io.Bu

  • Resolve pip/virtualenv fiasco after upgrading Python 2.5 to Python 2.6? 2011-03-24

    I upgraded Python 2.5 to Python 2.6 on my system and it's crapping out ( yeah, it's my fault but at least this isn't a high priority production server ). pip didnt work so I had to manually grab the latest pip which is compatible with Python 2.6. I n

  • How can I embed(create) an interactive python shell in my python program 2011-04-08

    Is is possible to start a interactive python shell in a python program? For example, I want to use this interactive python shell to inspect some program internal variables. --------------Solutions------------- The code module provides an interactive

  • Convert Python 3 to "simple" python that can be read by autodoc 2011-04-09

    I have a written a program in Python 3 and are using Sphinx to document it. Sphinx's autodoc is great, however it only works with Python 2. Some modules work fine in autodoc, however modules don't. Some examples: Python 2 complains about Python 3 sty

  • Run python script without the "python" keyword 2011-05-04

    How can I run a python script in Terminal on Mac without using the "python" keyword, without having to edit my existing python files? Right now I have to do this: python What I like to do is this: --------------Solutions----------

  • Is there a way to restart or reset the python interpreter within a python doctest? 2011-05-11

    I am writing a short tutorial, and would like to be able to run the examples therein using python's doctest using python -m doctest foo.txt There is a point in the tutorial at which I want to start using a new, clean python interpreter. Is there a me

Copyright (C), All Rights Reserved.

processed in 0.080 (s). 11 q(s)