Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Вытяните случайные ключи из словаря в Python, которые не равны друг другу

Автор вопроса: kiddsupremeОтветов: 6

Итак, я пытаюсь настроить викторину с несколькими вариантами ответов через 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. Я хотел создать функцию, которая будет работать до тех пор, пока все три клавиши не будут отличаться друг от друга. Наконец, он напечатает результат. Любые идеи? Заранее спасибо.

  • Просто чтобы улучшить свой вопрос: вы ссылаетесь на проблему, но неясно, что происходит, когда вы запускаете свой код. Argalatyr 19.08.2012

pythondictionaryfunction

Ответы

Ответ 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

Ответ 2 · рейтинг 3 · applicative_functor

Используйте 1_

>>> import random
>>> random.sample([1,2,3,4,5,6], 3)
[4, 5, 2]

Ответ 3 · Noctis Skytower

Может быть, вы хотели бы попробовать Quiz Me 2.5? Это система викторин с несколькими вариантами ответов с графическим интерфейсом на Python 3.x.

Ответ 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)!

Ответ 5 · Doug T.

Наверное, проще всего shuffle ключи:

keysShuffled = list(word_drills)
random.shuffle(keysShuffled)

Затем возьмите первые 3

threeUnique = keysShuffled[:3]

Ответ 6 · рейтинг -1 · Rob T

У меня была такая же проблема, и я написал https://github.com/robtandy/randomdict, чтобы решить ее. Может быть, это поможет и вам.

Он предоставляет объект python dict, но с дополнительными методами random_key, random_value и random_item. Все со сложностью выполнения O(1).

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы