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]]
asked Dec 24, 2017 at 15:51
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.
answered Dec 24, 2017 at 16:03
ayhanayhan
66.2k17 gold badges173 silver badges191 bronze badges
0
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
. :]
answered Dec 24, 2017 at 16:01
Dan GittikDan Gittik
3,2703 gold badges16 silver badges24 bronze badges
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
>>>
answered Dec 24, 2017 at 20:19
srikavineeharisrikavineehari
2,4041 gold badge10 silver badges21 bronze badges
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"]]
answered Dec 24, 2017 at 15:57
mehdi maickmehdi maick
3253 silver badges7 bronze badges
In Python, you can shuffle [= randomize] a list, string, and tuple with random.shuffle[]
and random.sample[]
.
- random — Generate pseudo-random numbers — Python 3.8.1 documentation
random.shuffle[]
shuffles a list in place, and random.sample[]
returns a new randomized list. random.sample[]
can also be used for a string and tuple.
random.shuffle[]
shuffles a list in placerandom.sample[]
returns a new shuffled list- How to shuffle a string and tuple
- Initialize the random number generator with
random.seed[]
If you want to sort in ascending or descending order or reverse instead of shuffling, see the following articles.
- Sort a list, string, tuple in Python [sort, sorted]
- Reverse a list, string, tuple in Python [reverse, reversed]
random.shuffle[]
shuffles a list in place
You can shuffle a list in place with random.shuffle[]
.
import random
l = list[range[5]]
print[l]
# [0, 1, 2, 3, 4]
random.shuffle[l]
print[l]
# [1, 0, 4, 3, 2]
random.sample[]
returns a new shuffled list
random.sample[]
returns a new shuffled list. The original list remains unchanged.
random.sample[]
returns random elements from a list. Pass the list to the first argument and the number of elements to return to the second
argument. See the following article for details.
- Random sampling from a list in Python [random.choice, sample, choices]
By setting the total number of elements in the list to the second argument, random.sample[]
returns a new list with all elements randomly shuffled. You can get the total number of elements in the list with len[]
.
l = list[range[5]]
print[l]
# [0, 1, 2, 3, 4]
lr = random.sample[l, len[l]]
print[lr]
# [0, 3, 1, 4, 2]
print[l]
# [0, 1, 2, 3, 4]
How to shuffle a string and tuple
Strings and tuples are immutable, so random.shuffle[]
that modifies the original object raises an error TypeError
.
s = 'abcde'
# random.shuffle[s]
# TypeError: 'str' object does not support item assignment
t = tuple[range[5]]
print[t]
# [0, 1, 2, 3, 4]
# random.shuffle[t]
# TypeError: 'tuple' object does not support item assignment
To shuffle strings or tuples, use random.sample[]
, which creates a new object.
random.sample[]
returns a list even when a string or tuple is specified to the first argument, so it is necessary to convert it to a string or tuple.
For strings, a list of characters is returned. Use the join[]
method to concatenate to a single string again.
- Concatenate strings in Python [+ operator, join, etc.]
sr = ''.join[random.sample[s, len[s]]]
print[sr]
# bedca
Use tuple[]
for tuples, which creates a tuple from a list.
- Convert list and tuple to each other in Python
tr = tuple[random.sample[t, len[l]]]
print[tr]
# [0, 1, 2, 4, 3]
Initialize the random number generator with random.seed[]
You can initialize a random number generator with random.seed[]
.
After initializing with the same seed, it is shuffled in the same way.
l = list[range[5]]
random.seed[0]
random.shuffle[l]
print[l]
# [2, 1, 0, 4, 3]
l = list[range[5]]
random.seed[0]
random.shuffle[l]
print[l]
# [2, 1, 0, 4, 3]