Pythonic idioms / Programming Puzzle
ameoba
ahmebah at hotmail.com
Sat Jan 19 08:51:51 EST 2002
The other day, I got caught up in nostalgia, and decided to look around at
some LOGO (y'know, turtle graphics &C) webzits. What to my wondering eyes
should appear but an acknowledgement that LOGO is a variant of LISP and -
not- just a toy language. To prove it there was an example program (
http://www.cs.berkeley.edu/~bh/logo-sample.html ) that printed permutations
of an arbitrary list of arbitrarily long lists of strings.
in 4 lines.
Python's a new thing for me, so in my newborn zeal, I decided to show that
Python could do it just as well, using lists defined like:
-------------
list = [["Small","Medium","Large"],
["Mountain Dew", "root beer", "orange juice"],
["\b, a"],
["hamburger", "cheeseburger", "double cheeseburger"],
["\b, and a"],
["small", "medium", "large"],
["fries."]]
-------------
So I essentially translated it to Python, which resulted in this:
----------
#recursive arbitrary list of lists permuter.
def choices(menu, sofar = ""):
if(menu == []) : print sofar.strip()
else :
for x in menu[0] : choices(menu[1:],sofar+" "+x)
----------
Which was fine and dandy, but I couldn't stop with simply translating
somebody elses work. I wanted to come up with an iterative solution, which
gave me :
----------
# arbitrary list of lists permuter. Iterative version.
# Esentially a series of different base N counters
# where N is determined by the length of the corresponding list
# with overflows carried over to the next place
def ichoices(menulist = []):
#init counter
counter = [0]*len(menulist)
#loop 'till counter overruns on last element
# (god I love reverse array indexing, sweet syntactic sugar)
while counter[-1] < len(menulist[-1]):
#build & print the combination
t = ""
for x in range(len(menulist)):
t += " " + menulist[x][counter[x]]
print t.strip()
#increment counter, and handle overflows by carry to next place
#except for the last place, since the overflow there
#is our termination condition
counter[0] += 1
for x in range(len(counter)-1):
if counter[x] >= len(menulist[x]):
counter[x] = 0
counter[x+1] += 1
----------
Which, at 12 lines of code, is longer but (perhaps just because I wrote it)
a bit easier to follow.
Looking at these two fundamentally different solutions to the same problem
got me thinking... Obviously, both of these solutions are correct and
fully functional, but is one a more Pythonic way of solving the problem, or
is there an even more Pythonic solution floating arround?
Another question; Does my code show that I have any perceptable 'accent'?
That is to ask, am I obviously influenced by the other languages I've
worked in (mostly C/Java/C++)?
More information about the Python-list
mailing list