我有一个从dict返回随机键/值的函数。
def heroes():
hero, attribute = random.choice(list(heroes.items()))
return(hero, attribute)
我在我的应用程序中多次调用此函数,我正在寻找一种方法来保证每个调用返回的值与前一个函数不同,是否可以轻松实现?
答案 0 :(得分:1)
这是一个函数,它接受一个字典并为它创建一个随机迭代器:
import random
def rand_items(d):
def g():
d_items = list(d.items())
random.shuffle(d_items)
for i in d_items:
yield i
return g()
#tested like:
hero = {'batman':'rope','spiderman':'web', 'superman':'cape'}
heroes = rand_items(hero)
for h in heroes:
print(h)
一次运行:
('spiderman', 'web')
('superman', 'cape')
('batman', 'rope')
你可以一次获得一个英雄。初始化为:
heroes = rand_items(hero)
然后,只要您需要英雄,只需使用next(heroes)
代替您的函数调用。
答案 1 :(得分:0)
我更喜欢使用装饰器。它允许你通过英雄无限循环。例如:
import random
# In this version heroes are global
HEROES = {'a':10, 'b':20, 'c':30, 'd':40}
def except_last_one(hero_func):
# storage for the last hero
last_hero = [None]
def new_hero():
# define a new hero (but not the last hero)
last_hero[0] = hero_func([k for k in HEROES.keys() if k != last_hero[0]])[0]
return (last_hero[0], HEROES[last_hero[0]])
return new_hero
@except_last_one
def hero(heroes=HEROES.keys()):
hero = random.choice(heroes)
return (hero, HEROES[hero])
如果你发表评论@except_last_one
,你获得的函数等于你的函数heroes()
。当你只有一个英雄时,我可能会添加一个例外来捕捉案例:
try:
last_hero[0] = hero_func([k for k in HEROES.keys() if k != last_hero[0]])[0]
except IndexError:
print 'Sorry, no heroes for you.'
return (None, None)