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
的长度为n
x
中不包含重复的元素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)