Reputation: 45
I'm trying to scramble a string, "string", without using random.shuffle()
, but my code keeps producing output that has missing and repeating characters, e.g. gtrgtg, gnrtnn, etc. I'm not sure what I'm doing wrong.
import random
s = "string"
new_s=[]
for c in s:
if random.choice(s) not in new_s:
new_s.append(random.choice(s))
print(''.join(new_s))
Upvotes: 0
Views: 3278
Reputation: 2612
Using while
, you could loop through s
until the length of new_s
matches with that of s
and the resultant string has non-repeating characters.
import random
s = "string"
new_s = '' # So you will not need ''.join() when you print this result
while len(new_s) != len(s):
char = random.choice(s)
if char not in new_s:
new_s += char
print(new_s)
rntigs
>>>
Upvotes: 1
Reputation:
In its current state, your program checks whether the randomly chosen character is in a string. If it is, it doesn't do anything other than continuing the loop. Also since you don't assign random.choice(s)
to a variable, you generate another character after you do the check.
A working version would be:
import random
s = "string"
new_s = []
for c in s:
char = random.choice(s) # assign it to a variable
while char in new_s: # until a new character comes, repeat the procedure
char = random.choice(s)
new_s.append(char)
print(''.join(new_s))
This generates strings like ngtsri
, gsrnit
, etc. Note that this won't work if you have duplicates in the original string.
The above code is highly inefficient. I only gave the correction assuming this was for learning purposes. Normally, if you want to repeatedly check if something is in a collection, that collection should be a set or a dictionary.
Upvotes: 3
Reputation: 3850
random.choice
choses a random character out of string s
, but doesn't remove it - so it's possible for the same character to be chosen multiple times, and for some characters to not be chosen at all.
import random
s = 'string'
new_s = []
# rather than choosing a character, chose an index, use it and slice it out
while s:
i = random.randint(0, len(s)-1)
new_s.append(s[i])
s = s[:i] + s[i+1:]
print(''.join(new_s))
# this is more elegant with lists:
s = list(s)
while s:
i = random.randint(0, len(s)-1)
new_s.append(s.pop(i))
print(''.join(new_s))
Neither option is very efficient... but for efficiency, use random.shuffle
. :)
Upvotes: 1
Reputation: 325
try this:
from random import randint
def shuffle(sr):
n = len(sr)
s = list(sr)
for i in range(n):
cur, idx = s[i], randint(0, n - 1)
s[i], s[idx] = s[idx], cur
return ''.join(s)
print(shuffle("hello"))
Upvotes: 0