the python way?

Steven Bethard steven.bethard at gmail.com
Mon Jun 6 14:52:10 EDT 2005


Grooooops wrote:
> Hi All,
> 
> I've been lurking the list for a month and this is my first post. I am
> hoping this post is appropriate here, otherwise, my apologies.
> 
>  I'm somewhat new to Python, (I'm reading all the tutorials I can find,
> and have read through Andre Lessa's Developers Handbook.)
> I am trying to learn the Python way of thinking as well as the syntax.
> 
> I popped this bit of code together for fun, based on a previous post
> regarding randomizing a word.
> This shuffles a word, then splits out the vowels and then reassembles
> it with the vowels interpolated between consonants.
> (To create plausible sounding gibberish)
> 
> The code just seems kind of bulky to me. I am wondering, is this an
> efficient way to do things, or am I making things harder than
> necessary?
> 
> #--------------------------begin code------------------
> """scrambles a word, but creates plausable gibberish"""
> import random
> def shuffled(s):
>         """ scrambles word"""
> 	l = list(s)
> 	random.shuffle(l)
> 	return ''.join(l)
> 
> def contains(alist,b):
>         """...is letter b in list a..."""
> 	ret = []
> 	for all in alist:
> 		#print all
> 		if all==b:
> 			return 1
> 	return 0

"contains(alist, b)" can be more easily written as "b in alist"


> 
> def newZip(a1,a2):
>         """ reassemble """
> 	l1=len(a1)
> 	l2=len(a2)
> 
> 	longest = [a1,a2][l1<l2]
> 	shortest = [a1,a2][longest == a1]

longest, shortest = sorted([a1, a2], key=len)

> 	diff = max(l1,l2)-min(l1,l2)
> 	#print longest
> 	seq = len(longest)
> 	ret = ""

Don't build up strings using +.  Create a list of strings, and use 
str.join at the end.

> 	for j in range(seq):
> 		if len(longest)>0:

The len() > 0 is unnecessary, simply use:

                 if longest:

> 			ret = ret + longest.pop()
> 		if len(shortest)>0:

                 if shortest:

> 			ret = ret + shortest.pop()
> 	return ret

If I understand you right, you want to do the usual thing zip does, but 
guaraneeing that the first element is always from the longer list, and 
not throwing away elements.  Note that map(None, ...) probably does what 
you want:

longest, shortest = sorted([a1, a2], key=len, reverse=True)
return ''.join(item
                for pair in map(None, longest, shortest)
                for item in pair
                if item is not None)


> def reinterpolate(word):
>         """ main function """
> 	wlist = shuffled(list(word))
> 	vlist = list('aeiouy') # ok, y isn't really a vowel, but...

no need to make vlist a list; contains should work fine on strings.

> 	vees = filter(lambda x: contains(vlist,x),wlist)

vees = [c in vlist for c in wlist]

> 	cons =  filter(lambda x: not(contains(vlist,x)),wlist)

cons = [c not in vlist for c in wlist]

> 	a=list(vees)
> 	b=list(cons)

The above are unnecessary.  vees and cons are already lists.

> 	return newZip(a,b)
> 
> word = "encyclopedia"
> print reinterpolate(word)

So I think overall, my rewrite of your code would look something like 
(untested):

def reinterpolate(word)
     wlist = list(word)
     random.shuffle(wlist)
     vlist = 'aeiouy'
     vees = [c for c in wlist if c in vlist]
     cons = [c for c in wlist if c not in vlist]
     longest, shortest = sorted([vees, cons], key=len)
     return ''.join(item
                    for pair in map(None, longest, shortest)
                    for item in pair
                    if item is not None)



More information about the Python-list mailing list