views:

222

answers:

7

how to shuffle a word's letters randomly in python? for example, we have the word "cat". change that randomly to, act, tac or tca and ex.. to be exact,The scrambling process must be implemented manually. Built-in functions or string methods that “automate” this process are prohibited from use. thanks

+5  A: 
import random
word = "cat"
shuffled = list(word)
random.shuffle(shuffled)
shuffled = ''.join(shuffled)
print shuffled

...or done in a different way, inspired by Dominic's answer...

import random
shuffled = ''.join(random.sample(word, len(word)))
icktoofay
`random.shuffle` does a shuffle in place, so you don't really need to set a new variable (but you can).
Bartek
@Bartek: Yes, I noticed that right after I posted it.
icktoofay
thank you for the help, but is there any way to do it not using the random.shuffle ?
babikar
You could write your own shuffle algorithm, but why not use the built-in library?
derekerdmann
Homework? I think so ;-)
Bartek
@Bartek: Ah, yes.
derekerdmann
yeh out teacher wont let us use the built-in functions!
babikar
Would you mind posting what you've done so far?
derekerdmann
I haven't done much cuz this is the only "hard"part of the lab that i was thinking about. if u want i can post my lab if you like to take a look at it?
babikar
No, that won't be needed since shuffling algorithms wouldn't be unique to the lab itself. It's just convention on SO to post any attempts you've made at the problem you've asked about.
derekerdmann
to be exact, this is what my teacher said: The scrambling process must be implemented manually. Built-in functions or string methods that “automate” this process are prohibited from use.
babikar
+2  A: 
return "".join(random.sample(word, len(word)))

Used like:

word = "Pocketknife"
print "".join(random.sample(word, len(word)))

>>> teenockpkfi
Dominic Bou-Samra
Why are you using `letter for letter in...`? `random.sample` returns a list; you don't need to make a generator expression from the list.
icktoofay
yeh why are you using letter fo letter in?
babikar
I have no idea...
Dominic Bou-Samra
+5  A: 

Take a look at the Fisher-Yates shuffle. It's extremely space and time-efficient, and easy to implement.

derekerdmann
A: 

To be very slightly more low level, this just swaps the current letter with a random letter which comes after it.

from random import randint
word = "helloworld"

def shuffle(word):
    wordlen = len(word)
    word = list(word)
    for i in range(0,wordlen-1):
        pos = randint(i+1,wordlen-1)
        word[i], word[pos] = word[pos], word[i]
    word = "".join(word)
    return word

print shuffle(word) 

This won't create all possible permutations with equal probability, but still might be alright for what you want

Jamie Wong
I'm pretty sure if you tweaked it so it swapped each letter with either itself or a random letter which comes after it, you suddenly have uniformity.
Anon.
A: 

Here is a way that doesn't use random.shuffle. Hopefully random.choice is ok. You should add any restrictions to the question

>>> from random import choice
>>> from itertools import permutations
>>> "".join(choice(list(permutations("cat"))))
'atc'

This method is not as efficient as random.shuffle, so will be slow for long words

gnibbler
What exactly will happen if you try running `list(permutations("01234567890123456789"))`? Does it throw an exception because it runs out of memory, or just lock up your computer trying to acquire it?
Jamie Wong
@Jamie Wong, Probably takes a long time and then runs out of memory. Unless you have a 64 bit system with a bazillion bytes of RAM :)
gnibbler
+3  A: 

This cookbook recipe has a simple implementation of Fisher-Yates shuffling in Python. Of course, since you have a string argument and must return a string, you'll need a first statement (say the argument name is s) like ary = list(s), and in the return statement you'll use ''.join to put the array of characters ary back into a single string.

Alex Martelli
A: 
from random import random
def shuffle(x):
    for i in reversed(xrange(1, len(x))):
        j = int(random() * (i+1))
        x[i], x[j] = x[j], x[i]
gnibbler
Please *don't* use random() * n when you mean random.randrange(n)
Marius Gedminas
@Marius Gedminas, but that's the way `shuffle()` is implemented in random.py ;o)
gnibbler
@gnibbler: Interesting! I wonder why? The implementation of randrange() has a comment saying "Note that int(istart + self.random()*width) instead would be incorrect". Perhaps that's only for values of istart != 0?
Marius Gedminas
Yes, I see now that the implementation of randrange(n) is precisely int(random() * n) when 0 < n < 2**53.
Marius Gedminas