0

I need to generate a fixed-length string with only 'y' and 'n' in a random order, and the number of 'n' in the string is determined by the variable Njk. The strings must be like 'yyyyynynynyyyyyy' or 'yynyyyynyyynyyyy', and I'll generate a huge amount of strings. Currently I'm doing like the code below. The problem is, to generate 200 strings of length 16, it works fine, but when I try to generate 200 strings of length 33, it takes so much time to execute that is making my work unviable. How can I do it in a optimal/efficient way?

Best regards!

#
chaves = 16
Njk = 3

#Generating a random key state
def rand_estado():
    aux2 = randint(0,1)
    if aux2 == 0:
        estado = 'n'
    if aux2 == 1:
        estado = 'y'
    return estado

#Generating a random combination of key states with fixed number of 'y' and 'n'       
def rand_estado_chaves():
    radialidade = 0
    #The condition that must be satisfied
    while (radialidade != chaves - Njk):
        estado_chaves = "" 
        #For each key
        for i in range(chaves):
            estado_chaves += rand_estado()
            radialidade = estado_chaves.count('y')
    return estado_chaves
2
  • Thank you all guys! It really helped me :D Commented Feb 12, 2020 at 13:16
  • It is highly recommended to accept the answer of your choice by clicking the green checkbox near it. Commented Feb 12, 2020 at 16:03

4 Answers 4

1

If you know the size of the final string and the number of N, you can create a list that starts with Njk N and length - Njk Y. Then, shuffle the list and join it.

from random import shuffle

final_size = 16
number_of_n = 3

# ['n', 'n', 'n', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y']
result = list('n' * number_of_n + 'y' * (final_size - number_of_n))
shuffle(result)
result = ''.join(result)
print(result)

This can output strings like this :

nyyyyyyyynyynyyy

nyyyyyyynyyyynyy

ynyynynyyyyyyyyy

Sign up to request clarification or add additional context in comments.

Comments

0

You can generate random strings with only 2 characters using random.choices by setting the weights. If you get more or fewer ns than you need, discard and get a new one. Below I did that with a recursive function.

import random

def yn_gen(num_n=5, size=30):
    candidate = random.choices('yn', 
        weights=((size-num_n)/size, num_n/size), 
        k=size)
    if candidate.count('n')==num_n:
        return ''.join(candidate)
    else:
        return yn_gen(num_n, size)

yn_gen()
# returns:
'yynnnnyyyyyyyyyyyyyyyyyyyynyyy'

yn_gen(10, 50)
# returns:
'yynynynnyyyyynyyyyyyynyynnyyyyyyyyyynyynyyyyyyyyyy'

Comments

0

Essentially, you need to choose the pre-defined number of positions where ns should be placed, and set everything else to y:

def generate(length, ns):
    result = ['y'] * length
    for i in random.sample(range(length), ns):
        result[i] = 'n'
    return ''.join(result)

Comments

0

The random module provides a function called sample that can be used to produce the random patterns very efficiently

from random import sample

size    = 33
count   = 200
NjK     = 7

yn      = ["n"]*NjK + ["y"]*(size-NjK)
results = [ "".join(sample(yn,size)) for _ in range(count) ]

print(results[:3],"...",results[-3:])

this will allow you to generate thousands of long patterns very fast.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.