我已经阅读了关于如何将列表分割成n个近乎相等长度的分片 [重复]问题的回答。
这是被接受的回答:
def partition(lst, n):
division = len(lst) / float(n)
return [ lst[int(round(division * i)): int(round(division * (i + 1)))] for i in xrange(n) ]
我想知道,如何修改这些解决方案以便将项目随机分配到一个分区,而不是递增地分配。
我已经阅读了关于如何将列表分割成n个近乎相等长度的分片 [重复]问题的回答。
这是被接受的回答:
def partition(lst, n):
division = len(lst) / float(n)
return [ lst[int(round(division * i)): int(round(division * (i + 1)))] for i in xrange(n) ]
我想知道,如何修改这些解决方案以便将项目随机分配到一个分区,而不是递增地分配。
完整的2018年解决方案(Python 3.6):
import random
def partition (list_in, n):
random.shuffle(list_in)
return [list_in[i::n] for i in range(n)]
注意!这可能会改变您原来的列表。
对输入列表进行随机排序。
首先,您需要将列表随机化,然后将其分成n个几乎相等的部分。
对列表进行洗牌并不保留顺序。你可以尝试使用以下方法(很容易适应于超过两个部分)。完全未经测试。
from __future__ import annotations
from typing import TypeVar
import random
T = TypeVar("T")
def partition_list(s: list[T]) -> tuple[list[T], list[T]]:
"""
Randomly partition a list into two lists, preserving order. The number to
take is drawn from a uniform distribution.
"""
len_a = random.randint(0, len(s))
len_b = len(s) - len_a
put_in_a = [True] * len_a + [False] * len_b
random.shuffle(put_in_a)
a: list[T] = []
b: list[T] = []
for val, in_a in zip(s, put_in_a):
if in_a:
a.append(val)
else:
b.append(val)
return a, b
def partition_preserve_order(list_in, n):
indices = list(range(len(list_in)))
shuffle(indices)
index_partitions = [sorted(indices[i::n]) for i in range(n)]
return [[list_in[i] for i in index_partition]
for index_partition in index_partitions]
(也就是说,我们对索引进行洗牌,然后在分区内对它们进行排序)
示例:
random_partition_preserve_order(list('abcdefghijklmnopqrstuvxyz'), 3)
# [
# ['c', 'd', 'g', 'm', 'p', 'r', 'v', 'x', 'y'],
# ['b', 'e', 'h', 'k', 'o', 'q', 't', 'u'],
# ['a', 'f', 'i', 'j', 'l', 'n', 's', 'z']
# ]