2

如何为给定序列的子序列编写策略?

例如给定一个list

elements = list(range(5))

我要策略

sub_elements = *strategy*(elements)

这会产生

[]
[0]
[0, 2]
[1, 3, 4]
[0, 1, 2, 3, 4]

结合strategies.lists&strategies.sampled_from的简单方法

>>> from hypothesis import strategies
>>> strategies.lists(strategies.sampled_from(elements))

不起作用,因为它没有考虑原始元素的数量。

4

1 回答 1

1

主要思想是使用strategies.slices然后根据它们选择项目

from collections import abc
from typing import TypeVar

from hypothesis import strategies
from hypothesis.strategies import SearchStrategy

Sequence = TypeVar('Sequence', bound=abc.Sequence)


def subsequences(sequence: Sequence) -> SearchStrategy[Sequence]:
    return strategies.builds(sequence.__getitem__,
                             strategies.slices(max(len(sequence), 1)))

它非常简短、直接,应该适用于任何支持切片的序列,如lists、tuples 和strings(即使对于ranges,这是很棒的 IMO)。

例子:

>>> elements = list(range(5))
>>> sub_elements = subsequences(elements)
[1, 3]
>>> sub_elements.example()
[4]
>>> sub_elements.example()
[0, 2, 4]

该方法的唯一问题是我们无法创建所有可能的子序列(例如[0, 1, 4]来自elementsOP)。

可以用strategies.permutationslike解决

from operator import getitem
from typing import (List,
                    Sequence,
                    TypeVar)

from hypothesis import strategies
from hypothesis.strategies import SearchStrategy

Element = TypeVar('Element')


def sub_lists(sequence: Sequence[Element]) -> SearchStrategy[List[Element]]:
    return strategies.builds(getitem,
                             strategies.permutations(sequence),
                             strategies.slices(max(len(sequence), 1)))

但我们失去了原始序列类型。

于 2020-06-14T17:25:26.397 回答