我怎样才能将随机元素插入到字典中,并在我调用它时将其随机化?

时间:2016-04-26 08:30:58

标签: python python-2.7 dictionary random

我正在编写一个Facebook机器人,它最终每天会产生一些随机生成的状态。现在,我正处于这样的阶段:我已经从字典条目中选择了一些短语并且我已经编写了它,因此它将暂时在Python shell中工作 - Facebook身份验证的内容将在稍后发布。

现在,我认为将字典中包含的短语中的某些名词随机化是很酷的,我使用random.choice()执行此操作并运行应返回新随机元素的函数每次我生成一个状态。但问题是,无论何时我称之为短语,我都可以看到它生成了一个随机名词,但该名词得到了修复'由于某种原因,每次都会再现相同的随机名词。当我将该函数作为构建状态的一部分运行时,它似乎工作正常,但由于某种原因我无法想象,任何新的随机名词都不会传递给字典。当然,它在我重新启动程序时起作用,但如果我打算以机器人的身份执行此操作,我理想情况下每次想要新状态时都不必重新启动程序。

我做了一些调查,我认为这个问题与我实际的random.choice()内容或他们所处的功能无关,但字典得到修复& #39;在我的随机名词功能可以触摸它之前(例如随机选择函数从水果列表中产生一个随机选择,但是当我运行StatusBuilder函数时,字典只会选择相同的水果)。我尝试了一些带有全局变量的潜在解决方案,等等,但没有任何效果。我认为,下面的代码中演示的摘录是我最接近的。

from random import randint
from random import choice
from textwrap import fill

def RandomFruit():
    return choice(["mango", "pomelo", "guava", "grapefruit", "watermelon"])

class DoTable():
    def __init__(self, text):
        self.text = text

DoDict = {
    "do0": DoTable("sitting on the roof, completely naked, throwing Herb Alpert records at a dog like they were frisbees"),
    "do1": DoTable("eating a " + RandomFruit() + " like it's a handfruit"),
    "do2": DoTable("lurching around a supermarket"),
    }

class BeTable():
    def __init__(self, start_text, end_text):
        self.start_text = start_text
        self.end_text = end_text

BeDict = {
    "be0": BeTable("I guess ", " is what my life has come to."),
    "be1": BeTable("", ", just waiting for the police to arrive."),
    "be2": BeTable("If ", " is wrong, then I don't ever want to be right!"),
    }

def StatusBuilder():
#DoDict and BeDict will always have one entry selected from each, though
#BeDict will always have two attributes selected as part of the one entry.
    DoRNG = randint(0,len(DoDict)-1)
    BeRNG = randint(0,len(BeDict)-1)
#Logic to display concatenated strings
    status = BeDict["be" + str(BeRNG)].start_text + DoDict["do" + str(DoRNG)].text + BeDict["be" + str(BeRNG)].end_text
#print the status with textwrapping and with the first letter always capitalised.
    print fill((status[0].capitalize() + status[1:]), 80)
    print
    Controls()

def Controls():
    command = raw_input("([RETURN] FOR ANOTHER ROUND OF BULLSHIT, [Q] TO QUIT): ")
    if command.lower() == "q":
        quit()
    elif command.lower() == "":
        print
        RandomFruit()
        StatusBuilder()
    else: 
        print
        print fill("Some kind of wise guy are you? Try again, this time with a PROPER command please.", 80)
        print
        Controls()

#Start the program
print "PHILBOT V1.0"
print "A social media status generator."
print
command = raw_input("(PRESS [RETURN] TO GET STARTED): ")
print
RandomFruit()
StatusBuilder()

示例词典包含在上面的代码中(这是一个大规模削减的程序版本,如果你想玩它就会运行)。因此,我遇到问题的输出将是DoDict中带有键" do1"的元素。例如,假设StatusBuilder函数连续选择相同的短语(" do1"和#34; be2"),我想要它做的是每次调用时产生不同的水果StatusBuilder函数,如下所示:

"如果像吃芒果一样,手提果是错的,那我就不想做对了!"

"如果像吃葡萄柚一样,手提果是错的,那么我就不会想要做对了!"

目前,无论选择哪种水果,都要坚持使用。永久每当我通过StatusBuilder()运行它时,即使RandomFruit()函数似乎正常工作。

编辑:我现在尝试了一些建议的替代方案(使用lambda和使用生成器),并尝试使用更简单的数据格式(没有类的列表),但问题仍在重现。所以,我开始认为它更多地与我的操作顺序有关,就像在词典条目中写的那样#39;'在最初运行RandomFruit函数之后(yay!),但它没有被重写?'当我再次运行它时(嘘!)...这给了我一个问题,因为我可以声明函数然后声明字典(函数在首次使用后似乎没有对字典说话) ,或者然后将字典声明为函数(由于字典然后试图依赖于尚未声明的函数,因此该函数不起作用)。所以,我认为这是问题的根源 - 任何帮助?

1 个答案:

答案 0 :(得分:5)

您可以使用random.choice函数作为字典中的值(我已经简化了您的示例):

import random
fruits = ["mango", "pomelo", "guava", "grapefruit", "watermelon"]
DoDict = {'do1': random.choice}

这样,每次访问字典时都会获得一个随机的水果:

>>> for i in range(10): print DoDict['do1'](fruits)
guava
pomelo
watermelon
mango
watermelon
grapefruit
pomelo
watermelon
watermelon
watermelon

您还可以使用生成器

def random_fruit():
    while True:
        yield random.choice(["mango", "pomelo", "guava", "grapefruit", "watermelon"])
DoDict = {'do1': random_fruit().next}

在这种情况下,您不需要将水果列表作为参数传递:

>>> for i in range(10): print DoDict['do1']()
grapefruit
pomelo
pomelo
guava
grapefruit
pomelo
pomelo
pomelo
mango
guava