Итак, я пытаюсь настроить викторину с несколькими вариантами ответов через Python. Я новичок в Python, поэтому заранее извиняюсь, если есть более простой способ сделать это. Тем не менее, я пытаюсь действительно понять некоторые основы, прежде чем переходить к более новым методам.
У меня есть словарь. В этом словаре я хочу получить 3 случайных ключа. Я также хочу убедиться, что эти три ключа не равны (другими словами, случайны друг от друга). Вот код, который я написал до сих пор:
import random
word_drills = {'class': 'Tell Python to make a new kind of thing.',
'object': 'Two meanings: the most basic kind of thing, and any instance of some thing.',
'instance': 'What you get when you tell Python to create a class.',
'def': 'How you define a function inside a class.',
'self': 'Inside the functions in a class, self is a variable for the instance/object being accessed.',
'inheritance': 'The concept that one class can inherit traits from another class, much like you and your parents.',
'composition': 'The concept that a class can be composed of other classes as parts, much like how a car has wheels.',
'attribute': 'A property classes have that are from composition and are usually variables.',
'is-a': 'A phrase to say that something inherits from another, as in a Salmon *** Fish',
'has-a': 'A phrase to say that something is composed of other things or has a trait, as in a Salmon *** mouth.'}
key1 = ' '
key2 = ' '
key3 = ' '
def nodupchoice():
while key1 == key2 == key3:
key1 = random.choice(word_drills.keys())
key2 = random.choice(word_drills.keys())
key3 = random.choice(word_drills.keys())
nodupchoice()
print "Key #1: %s, Key #2: %s, Key #3: %s" % (key1, key2, key3)
Я почти уверен, что проблема связана с моим циклом while. Я хотел создать функцию, которая будет работать до тех пор, пока все три клавиши не будут отличаться друг от друга. Наконец, он напечатает результат. Любые идеи? Заранее спасибо.
Ответ 1 · рейтинг 12 · DSM
Вы можете использовать random.sample:
>>> random.sample(word_drills, 3)
['has-a', 'attribute', 'instance']
и .keys() не надо, итерация по словарю идет по ключам.
Обратите внимание, что random.sample вернет три уникальных значения из предоставленного вами списка (т. е. никогда не вернет 'has-a' дважды):
>>> all(len(set(random.sample(word_drills, 3))) == 3 for i in range(10**5))
True
Ответ 4 · dbr
Как объясняли другие, random.sample - лучший способ сделать то, что вы хотеть.
Чтобы объяснить, почему ваш исходный код не работал:
Первая проблема, в вашем цикле while есть логическая ошибка - он завершится, как только два элемента станут разными (например, 'a' == 'a' == 'b' равно True, и цикл завершится), чтобы исправить это, есть несколько способов:
while not (key1 != key2 != key3):
В качестве альтернативы set может содержать только уникальные элементы, поэтому, когда длина set([key1, key2, key3]) равна 3, все три значения различны:
while len(set([key1, key2, key3]) != 3:
Вторая проблема и причина, по которой код отказывается запускаться:
key1 key2 key3 определены как глобальные переменные (файл key1 = ' ' are at the top-level of your.py`, а не в функции)
Вы можете без проблем найти глобальную переменную в функции (например, где вы сделали while key1 == key2 ...). Ошибка возникает из-за того, что вы также пытаетесь назначить значение key1 в своем цикле - это сбивает с толку синтаксический анализатор Python, поскольку вы ищете глобальную переменную в части while key1 == ..., но пытаетесь создать новую локальную переменную функции. на следующей строке, поэтому он выдает ошибку.
Мусорный способ исправить это выглядит так:
key1 = ' '
key2 = ' '
key3 = ' '
def nodupchoice():
global key1
global key2
global key3
while not (key1 != key2 != key3):
key1 = random.choice(word_drills.keys())
key2 = random.choice(word_drills.keys())
key3 = random.choice(word_drills.keys())
Тогда это будет работать так, как вы предполагали, но не делайте этого - глобальные переменные имеют свое применение, но это не та ситуация..
Вместо использования глобальной переменной вы можете легко вернуть несколько значений из функции:
def nodupchoice():
key1 = ' ' # local variables, which are inaccessible outside this function
key2 = ' '
key3 = ' '
while not (key1 != key2 != key3):
key1 = random.choice(word_drills.keys())
key2 = random.choice(word_drills.keys())
key3 = random.choice(word_drills.keys())
return key1, key2, key3
key1, key2, key3 = nodupchoice()
print "Key #1: %s, Key #2: %s, Key #3: %s" % (key1, key2, key3)
О, и даже лучше, вы можете передать word_drills в качестве аргумента:
def nodupchoice(things):
key1 = ' ' # local variables, which are inaccessible outside this function
key2 = ' '
key3 = ' '
while not (key1 != key2 != key3):
key1 = random.choice(things)
key2 = random.choice(things)
key3 = random.choice(things)
return key1, key2, key3
key1, key2, key3 = nodupchoice(word_drills)
... и вы написали функцию, почти идентичную random.sample(word_drills, 3)!