P124: Lotto: Draw N different random numbers from the set 1..M
乐透:从包含1到M整数的集合中随机抽取N个不同的数字。这个就用一副扑克牌中抽取若干张牌的抽象化。从大小为M的集合中抽取N个元素的解不是唯一(当M>N时)。所以,不能直接比较实际值和期望值来测试实现是否正确。而祇能判断实际值是否属于可行解的集合。假设,给定列表l包含1至M的整数,从l中抽取n个不重复的元素组成新的列表x。x必须满足以下三个条件:
x的长度为nx中不包含重复的元素x中每一个元素都属于l
完整的测试用例代码:
from python99.lists.p124 import lotto
import functools
import operator
def test_lotto():
m = 46
n = 6
l = [e for e in range(1, m+1)]
actual = lotto(n, m)
assert len(actual) == n
assert functools.reduce(
operator.and_, [e in l for e in actual], True) == True
assert len(actual) == len(set(actual))
assert functools.reduce(
operator.and_, [e in l for e in actual], True) == True
在range和random.sample的帮助下可以很方便地实现。
# Lotto: Draw N different random numbers from the set 1..M
# The selected numbers shall be put into a result list
import random
def lotto(n, m):
return random.sample(range(1, m+1), n)