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