Generating a random subsequence
Alex Martelli
aleax at aleax.it
Tue Jan 8 10:54:15 EST 2002
"Martin v. Loewis" <martin at v.loewis.de> wrote in message
news:m3n0zpivp9.fsf at mira.informatik.hu-berlin.de...
> Tom Bryan <tbryan at python.net> writes:
>
> > def randomSubseq( seq, length ):
>
> What would be wrong with
>
> return random.shuffle(seq[:])[:length]
random.shuffle takes a MUTABLE sequence (typically a list),
shuffles it in-place, and returns None. Thus, this code
would not work.
> I don't see the value of shuffling the indices.
I've already posted a version that shuffles a temp=list(seq)
instead (a tiny bit more direct, I think). But returning a
result of the same type as seq (e.g. a string when called
as randomSubseq("weltanshaung",6)) does requiring slightly
more delicate handling than just returning a list would.
It's unfortunate that there's no smooth and seamless way to
make a sequence-of-arbitrary-type except by a loop such as
those in Tom's original solution or my variation thereon.
Alas, type(seq)(temp[:length]) doesn't work well when seq
is a string. Maybe something like:
temp = list(seq)
random.shuffle(temp)
try:
joiner = seq[0:0].join
if not callable(joiner): raise AttributeError
except AttributeError:
joiner = type(seq)
return joiner(temp[:length])
would be an acceptable way to avoid the loop (in Python
2.2, of course) -- it would work for seq being a list,
tuple, string, or Unicode object -- but it seems somewhat
obscure and potentially fragile. Maybe just as a last-
ditch optimization, using instead the loop:
result = seq[0:0]
for item in temp[:length]: result += item
return result
as the "normal" approach otherwise.
Alex
More information about the Python-list
mailing list