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

1 python random dictionary python-2.7

我正在写一个Facebook机器人,它最终会产生一些随机生成的状态.现在,我正处于这样的阶段:我已经有了从字典条目中选择短语的逻辑,并且我已经编写了它,因此它将暂时在Python shell中工作 - Facebook认证的东西将会到来后来.

但是现在,我认为在字典中包含的短语中随机化某些名词是很酷的,我这样做random.choice()并运行一个函数,每当我生成一个状态时它应该返回一个新的随机元素.但问题是每当我调用这个短语时,我都可以看到它生成了一个随机名词,但该名词由于某种原因变得"固定",因此每次都会复制相同的随机名词.当我将该函数作为构建状态的一部分运行时,它似乎工作正常,但由于某种原因我无法想象,任何新的随机名词都不会传递给字典.当然,它在重新启动程序时有效,但如果我的目标是作为机器人这样做,我理想的是每次想要新状态时都不必重新启动程序.

我做了一些调查,我认为这个问题与我的实际random.choice()内容或它们所处的功能无关,而是在我的随机名词功能触及它之前字典得到"修复"(例如随机选择功能)从水果列表中生成一个随机选择,但是当我运行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()
Run Code Online (Sandbox Code Playgroud)

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

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

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

目前,无论何时通过StatusBuilder()运行它,首先选择哪个水果,即使RandomFruit()函数似乎正常工作.

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

Ton*_*has 5

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

import random
fruits = ["mango", "pomelo", "guava", "grapefruit", "watermelon"]
DoDict = {'do1': random.choice}
Run Code Online (Sandbox Code Playgroud)

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

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

你也可以使用一个发电机:

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

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

>>> for i in range(10): print DoDict['do1']()
grapefruit
pomelo
pomelo
guava
grapefruit
pomelo
pomelo
pomelo
mango
guava
Run Code Online (Sandbox Code Playgroud)