Last active
October 14, 2022 14:58
-
-
Save danesherbs/5cc6fd74abbb66c15effc2e266e3ce8e to your computer and use it in GitHub Desktop.
Function to sample without replacement and optionally include or exclude items
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def sample(seq: Sequence, k: int, include: Union[None, set] = None, exclude: Union[None, set] = None) -> Sequence: | |
"""Samples `k` items from `seq` without replacement, optionally including or excluding items.""" | |
# pre-condition | |
assert k >= 0, "Number of items to sample must be non-negative" | |
assert k <= len(seq), f"Cannot sample {k} items without replacement from a sequence with {len(seq)} items" | |
if include is None: | |
include = set() | |
if exclude is None: | |
exclude = set() | |
filtered_exclude = set(item for item in exclude if item in seq) | |
assert len(include) <= k, "Number of items to include can't exceed number of items to sample" | |
assert len(seq) - len(filtered_exclude) >= k, "Not enough items to sample from sequence after excluding items" | |
assert len(include.intersection(exclude)) == 0, "Sets `include` and `exclude` must be mutually exclusive" | |
# sample | |
filtered_seq = [item for item in seq if item not in include.union(exclude)] | |
sampled = random.sample(filtered_seq, k-len(include)) + list(include) | |
sampled = random.sample(sampled, k) | |
# post-condition | |
assert len(sampled) == k, "Sampled items must be of length `k`" | |
for item in include: | |
assert item in sampled, "Sampled items must include all items in `include`" | |
for item in exclude: | |
assert item not in sampled, "Sampled items must not include any items in `exclude`" | |
return sampled | |
sample(["dog", "cat", "lizard"], k=2, include={"dog"}, exclude={"lizard"}) # ["dog", "cat"] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment