Most elegant way to generate 3-char sequence

R

Rob Cowie

Hi all,

I wish to generate a sequence of the form 'aaa', 'aab', aac'.... 'aba',
'abb', 'abc' etc. all the way to 'zzz'.

How would you construct a generator to acheive this?

A simple, working but somewhat inelegant solution is...

alpha = ['a','b','c','d'] #shortened for brevity
alpha2 = ['a','b','c','d']
alpha3 = ['a','b','c','d']

def generator():
for char in alpha:
for char2 in alpha2:
for char3 in alpha3:
yield char + char2 + char3

x = generate()
x.next() # etc, etc, etc,
 
J

James Stroud

Rob said:
Hi all,

I wish to generate a sequence of the form 'aaa', 'aab', aac'.... 'aba',
'abb', 'abc' etc. all the way to 'zzz'.

How would you construct a generator to acheive this?

A simple, working but somewhat inelegant solution is...

alpha = ['a','b','c','d'] #shortened for brevity
alpha2 = ['a','b','c','d']
alpha3 = ['a','b','c','d']

def generator():
for char in alpha:
for char2 in alpha2:
for char3 in alpha3:
yield char + char2 + char3

x = generate()
x.next() # etc, etc, etc,

import string
alpha = string.lowercase

def generator(choices, length):
for a in choices:
if length > 1:
for g in generator(choices, length-1):
yield a + g
else:
yield a

for a in generator(alpha, 3):
print a


--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
J

James Stroud

Rob said:
Hi all,

I wish to generate a sequence of the form 'aaa', 'aab', aac'.... 'aba',
'abb', 'abc' etc. all the way to 'zzz'.

How would you construct a generator to acheive this?

A simple, working but somewhat inelegant solution is...

alpha = ['a','b','c','d'] #shortened for brevity
alpha2 = ['a','b','c','d']
alpha3 = ['a','b','c','d']

def generator():
for char in alpha:
for char2 in alpha2:
for char3 in alpha3:
yield char + char2 + char3

x = generate()
x.next() # etc, etc, etc,

A touch more efficient:

import string
alpha = string.lowercase

def generator(choices, length):
length -= 1
for a in choices:
if length:
for g in generator(choices, length):
yield a + g
else:
yield a

for a in generator(alpha, 3):
print a

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
D

David Isaac

Rob Cowie said:
alpha = ['a','b','c','d'] #shortened for brevity
alpha2 = ['a','b','c','d']
alpha3 = ['a','b','c','d']

def generator():
for char in alpha:
for char2 in alpha2:
for char3 in alpha3:
yield char + char2 + char3

Basically fine, but you only need one string. E.g.,
alpha = "abcd"
used three times.

Alan Isaac
 
G

Grant Edwards

Hi all,

I wish to generate a sequence of the form 'aaa', 'aab', aac'.... 'aba',
'abb', 'abc' etc. all the way to 'zzz'.

How would you construct a generator to acheive this?

A simple, working but somewhat inelegant solution is...

alpha = ['a','b','c','d'] #shortened for brevity
alpha2 = ['a','b','c','d']
alpha3 = ['a','b','c','d']

def generator():
for char in alpha:
for char2 in alpha2:
for char3 in alpha3:
yield char + char2 + char3

Why three separate lists? Why not

alpha = ['a','b','c','d'] #shortened for brevity

def generator():
for char in alpha:
for char2 in alpha:
for char3 in alpha:
yield char + char2 + char3
 
J

John Machin

Hi all,

I wish to generate a sequence of the form 'aaa', 'aab', aac'.... 'aba',
'abb', 'abc' etc. all the way to 'zzz'.

How would you construct a generator to acheive this?

A simple, working but somewhat inelegant solution is...

You're not wrong.
alpha = ['a','b','c','d'] #shortened for brevity

Hope you remember the alphabet correctly.
Why type all that punctuation?
Any reason this cruft is global (i.e. not local to the generator)?
alpha2 = ['a','b','c','d']
alpha3 = ['a','b','c','d']

Hope you get the redundant copy/paste right.
def generator():
for char in alpha:

Why stop at two spaces? One-space indentation is syntactically correct :)
for char2 in alpha2:
for char3 in alpha3:
yield char + char2 + char3

x = generate()

Did you meant "generator"?
x.next() # etc, etc, etc,

|>> def generator():
.... import string
.... alpha = string.ascii_lowercase
.... for char in alpha:
.... for char2 in alpha:
.... for char3 in alpha:
.... yield char + char2 + char3
....
|>> x = generator()
|>> the_lot = list(x)
|>> len(the_lot) == 26 ** 3
True
|>> [the_lot for i in (0, 1, 25, 26, -27, -26, -1)]
['aaa', 'aab', 'aaz', 'aba', 'zyz', 'zza', 'zzz']

Cheers,
John
 
D

David Isaac

alpha = string.lowercase
x=(a+b+c for a in alpha for b in alpha for c in alpha)
 
J

James Stroud

Rob said:
Hi all,

I wish to generate a sequence of the form 'aaa', 'aab', aac'.... 'aba',
'abb', 'abc' etc. all the way to 'zzz'.

How would you construct a generator to acheive this?

A simple, working but somewhat inelegant solution is...

alpha = ['a','b','c','d'] #shortened for brevity
alpha2 = ['a','b','c','d']
alpha3 = ['a','b','c','d']

def generator():
for char in alpha:
for char2 in alpha2:
for char3 in alpha3:
yield char + char2 + char3

x = generate()
x.next() # etc, etc, etc,

Yet a little more efficient.

import string
alpha = string.lowercase

def generator(choices, length):
length -= 1
if length:
for a in choices:
for g in generator(choices, length):
yield a + g
else:
for a in choices:
yield a

for a in generator(alpha, 3):
print a

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
J

James Stroud

SuperHik said:
and the winner is... :D

Not necessarily vying for winner, but David's solution is highly
specific as it doesn't do so well for something like

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab
..
..
..
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzy
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz


James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
R

Rob Cowie

John said:
Hi all,

I wish to generate a sequence of the form 'aaa', 'aab', aac'.... 'aba',
'abb', 'abc' etc. all the way to 'zzz'.

How would you construct a generator to acheive this?

A simple, working but somewhat inelegant solution is...

You're not wrong.
alpha = ['a','b','c','d'] #shortened for brevity

Hope you remember the alphabet correctly.
Not sure I understand your point. Why would I forget the alphabet?
Why type all that punctuation?
What punctuation?
Any reason this cruft is global (i.e. not local to the generator)? No
alpha2 = ['a','b','c','d']
alpha3 = ['a','b','c','d']

Hope you get the redundant copy/paste right.
Again, I don't understand what you mean
Why stop at two spaces? One-space indentation is syntactically correct :)
As are 3, 4 and 5 space indentation. Yet again, what is your point?
for char2 in alpha2:
for char3 in alpha3:
yield char + char2 + char3

x = generate()

Did you meant "generator"? Yes, made a mistake
x.next() # etc, etc, etc,

|>> def generator():
... import string
... alpha = string.ascii_lowercase
... for char in alpha:
... for char2 in alpha:
... for char3 in alpha:
... yield char + char2 + char3
...
|>> x = generator()
|>> the_lot = list(x)
|>> len(the_lot) == 26 ** 3
True
|>> [the_lot for i in (0, 1, 25, 26, -27, -26, -1)]
['aaa', 'aab', 'aaz', 'aba', 'zyz', 'zza', 'zzz']

Cheers,
John


I'm aware the code I posted is not great - it isn't code I would
consider using. It was only intended to serve as an illustration of the
task at hand in case my explanation wasn't sufficient.

I'm grateful to you for using list(generator) in your example. I was
not aware this could be done (I haven't yet fully read the generator
documentation).

Rob C
 
J

John Machin

John said:
Hi all,

I wish to generate a sequence of the form 'aaa', 'aab', aac'.... 'aba',
'abb', 'abc' etc. all the way to 'zzz'.

How would you construct a generator to acheive this?

A simple, working but somewhat inelegant solution is...
You're not wrong.
alpha = ['a','b','c','d'] #shortened for brevity
Hope you remember the alphabet correctly.
Not sure I understand your point. Why would I forget the alphabet?

.... or mistype it? If you use string.ascii_lowercase, your readers know
what is intended without checking that it is in fact that.
What punctuation?

Refer to the effbot's post.

The point being that gizmoids should not be given a wider visibility
than is required. A handy side effect is that it is more efficient to
reference a local than a global (global names have to be looked up in a
dictionary).
alpha2 = ['a','b','c','d']
alpha3 = ['a','b','c','d']
Hope you get the redundant copy/paste right.
Again, I don't understand what you mean

You need only one alpha, not 3. Otherwise your readers have to compare
alpha to alpha2 and alpha2 to alpha3 to ascertain that you haven't typoed.
As are 3, 4 and 5 space indentation. Yet again, what is your point?

4-space indentation is more or less standard. 2-space indentation is
definitely not an aid to swift comprehension of Python code.
for char2 in alpha2:
for char3 in alpha3:
yield char + char2 + char3

x = generate()
Did you meant "generator"? Yes, made a mistake
x.next() # etc, etc, etc,
|>> def generator():
... import string
... alpha = string.ascii_lowercase
... for char in alpha:
... for char2 in alpha:
... for char3 in alpha:
... yield char + char2 + char3
...
|>> x = generator()
|>> the_lot = list(x)
|>> len(the_lot) == 26 ** 3
True
|>> [the_lot for i in (0, 1, 25, 26, -27, -26, -1)]
['aaa', 'aab', 'aaz', 'aba', 'zyz', 'zza', 'zzz']

Cheers,
John


I'm aware the code I posted is not great - it isn't code I would
consider using.


If you wouldn't consider using it, don't drag it out in public. Some
n00b might think it the epitome of good style :)
It was only intended to serve as an illustration of the
task at hand in case my explanation wasn't sufficient.

I'm grateful to you for using list(generator) in your example. I was
not aware this could be done (I haven't yet fully read the generator
documentation).

A generator is an iterable. list(), sum(), max(), min(), enumerate(),
zip() etc work on iterables. It's that simple, and that powerful.

You might be interested in the itertools standard module as well.

Cheers,
John
 
S

SuperHik

James said:
Not necessarily vying for winner, but David's solution is highly
specific as it doesn't do so well for something like

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab
.
.
.
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzy
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

Right. But that wasn't the question :p
 
S

Steve Holden

James said:
Rob said:
Hi all,

I wish to generate a sequence of the form 'aaa', 'aab', aac'.... 'aba',
'abb', 'abc' etc. all the way to 'zzz'.

How would you construct a generator to acheive this?

A simple, working but somewhat inelegant solution is...

alpha = ['a','b','c','d'] #shortened for brevity
alpha2 = ['a','b','c','d']
alpha3 = ['a','b','c','d']

def generator():
for char in alpha:
for char2 in alpha2:
for char3 in alpha3:
yield char + char2 + char3

x = generate()
x.next() # etc, etc, etc,


A touch more efficient:

import string
alpha = string.lowercase

def generator(choices, length):
length -= 1
for a in choices:
if length:
for g in generator(choices, length):
yield a + g
else:
yield a

for a in generator(alpha, 3):
print a
Frankly, this doesn't seem more elegant than the original, particularly
once it uses a single string.

regards
Steve
 
S

Steve Holden

James said:
Not necessarily vying for winner, but David's solution is highly
specific as it doesn't do so well for something like

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab
.
.
.
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzy
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
You can't justify your solution by requirements gold-plating ... see the
subject line :)

regards
Steve
 
J

James Stroud

Steve said:
James said:
Rob said:
Hi all,

I wish to generate a sequence of the form 'aaa', 'aab', aac'.... 'aba',
'abb', 'abc' etc. all the way to 'zzz'.

How would you construct a generator to acheive this?

A simple, working but somewhat inelegant solution is...

alpha = ['a','b','c','d'] #shortened for brevity
alpha2 = ['a','b','c','d']
alpha3 = ['a','b','c','d']

def generator():
for char in alpha:
for char2 in alpha2:
for char3 in alpha3:
yield char + char2 + char3

x = generate()
x.next() # etc, etc, etc,


A touch more efficient:

import string
alpha = string.lowercase

def generator(choices, length):
length -= 1
for a in choices:
if length:
for g in generator(choices, length):
yield a + g
else:
yield a

for a in generator(alpha, 3):
print a
Frankly, this doesn't seem more elegant than the original, particularly
once it uses a single string.

regards
Steve

Are you sure you understand what each do?

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top