Can I print only one of these questions at a time?

Viewed 82

I need to randomise some questions and get one question at a time. I have about 200 questions in my list and I want my python code to randomly pick one out of the 200. I then want it to remove all questions that have already been printed from the list so that they cannot show up again. My current code randomises the order in which these questions come out. Is there a way to make it so the first question in the output is printed and then the second is printed and then the third one at a time? This is how my code looks (except with 200 questions):

import random

questions = [
    'define math',
    'define french',
    'define english',
    'define spanish',
    'define czech',
    'define slovak',
    'define whatever',
]

while questions:

    index = random.randrange(0, len(questions))

    selected = questions[index]
    questions.pop(index)
    
    print(selected)

And my output(which will look different every time it’s run because its random) looks like this

define czech
define math
define whatever
define french
define english
define slovak
define spanish

Can I make it so ‘define czech’ is printed on its own and then when I run the code again, ‘define math’ comes up and then ‘define whatever’ comes up in that randomised order? Any help will be appreciated!

3 Answers

random.choice to choose one element at a time and random.choices with choices limit, to pick up how many elements to choose, here i set it to 3. And picked_questions list will check if the question is repeated or not.

import random

questions = [
    'define math',
    'define french',
    'define english',
    'define spanish',
    'define czech',
    'define slovak']
    
elems = random.choices(questions, k=3) # using choices this time and limit them to pick up 3 random elements you can set it to 1 to meet ur needs.i just wanna show u a method which match ur actual and next needs

picked_questions = ["define english", "define spanish", "define slovak"] # suppose those questions are already picked to check the condition success

for i in elems:
  for x in picked_questions:
    if i not in picked_questions:
      picked_questions.append(i)  # this could be optimized using list comprehension

print(elems, '\n') 
print(picked_questions)

random output with 3 choices

['define english', 'define math', 'define czech'] # 3 random elements are picked up

['define english', 'define spanish', 'define slovak', 'define math', 'define czech'] # no repeated questions, math and czech questions are appended coz they are not repeated. 

random output with 1 choice by setting k = 1

['define czech'] 

['define english', 'define spanish', 'define slovak', 'define czech']

successfully done

Use list.remove to remove used question and yield to return random question and stop.


import random

questions = [
    'define math',
    'define french',
    'define english',
    'define spanish',
    'define czech',
    'define slovak',
    'define whatever',
]


def question_generator(data):
    while data:
        out_q = random.choice(data)
        yield out_q
        data.remove(out_q)


out_question = question_generator(questions)

Now you can just call next to get random question until no more data


try:
    random_question = next(out_question)
    print(random_question)

except StopIteration:
     print('No more questions')
     random_question = None

# do other stuff here. 
# call again (Best to run in try except StopIteration, as that is raise if we have consumed all questions.

another_q = next(out_question) 
print(another_q)

The idea is to use something like asynchronously flow. Yield will give us the value and pause the flow until we resume again. When no more values are left, StopIteration. error is raise. Now we catch it and return None.

use random.shuffle, with O(1) in space complexity(if shuffle in-place) and O(n) time complexity.

random_questions is what you want

import random

origin_questions = [
    'define math',
    'define french',
    'define english',
    'define spanish',
    'define czech',
    'define slovak',
    'define whatever',
]
random_questions = origin_questions[:]
for i in range(10):
    random.shuffle(random_questions)
    print(random_questions)

output

['define english', 'define french', 'define czech', 'define math', 'define spanish', 'define whatever', 'define slovak']
['define spanish', 'define czech', 'define french', 'define whatever', 'define math', 'define slovak', 'define english']
['define math', 'define english', 'define slovak', 'define whatever', 'define czech', 'define french', 'define spanish']
['define spanish', 'define czech', 'define english', 'define math', 'define whatever', 'define slovak', 'define french']
['define math', 'define slovak', 'define french', 'define whatever', 'define spanish', 'define english', 'define czech']
['define slovak', 'define whatever', 'define english', 'define spanish', 'define math', 'define czech', 'define french']
['define spanish', 'define math', 'define french', 'define slovak', 'define english', 'define czech', 'define whatever']
['define math', 'define whatever', 'define czech', 'define spanish', 'define french', 'define english', 'define slovak']
['define spanish', 'define math', 'define english', 'define slovak', 'define czech', 'define whatever', 'define french']
['define whatever', 'define english', 'define french', 'define spanish', 'define czech', 'define math', 'define slovak']

EDIT: generator recipe

import random

questions = [
    'define math',
    'define french',
    'define english',
    'define spanish',
    'define czech',
    'define slovak',
    'define whatever',
]

def gen_random_questions(origin_questions):
    random_questions = origin_questions[:]
    random.shuffle(random_questions)
    for i in random_questions:
        yield i
        
for question in gen_random_questions(questions):
    print(question)

output

define whatever
define spanish
define english
define slovak
define french
define math
define czech
Related