如果我理解正确,您有一个包含 448 个项目的列表(出于该算法的目的,这些项目是不透明的)。它们的初始顺序决定了它们的类别,每组 56 个对应一个不同的类别(因此总共有 8 个类别)。
您希望获得 14 个列表的输出,每个列表都有来自每个类别的四个项目。
这是我将如何做的大纲:
- 首先,对列表进行切片以获取单独的类别。
- 接下来,使用 打乱类别列表
random.shuffle
。
- 接下来,使用
zip
将 8 个 56 项的列表变成 56 个 8 项的列表。
- 接下来,一次取四个值,
zip
在重复的迭代器上再次使用。
- 最后,使用 将值组合到最终列表中
itertools.chain.from_iterable
。
编码:
import itertools
import random
def make_lists(input_list):
categories = [input_list[i:i+56] for i in range(0, 448, 56)] # 8 lists of 56
for c in categories:
random.shuffle(c)
selections = zip(*categories) # 56 tuples of 8
it = iter(selections)
by_four = zip(it, it, it, it) # 14 tuples of 4 tuples of 8
results = [list(itertools.chain.from_iterable(lst)) for lst in by_four]
return results
这是一个在整数列表上运行的示例:
>>> for lst in make_lists(list(range(448))):
print(lst)
[47, 104, 114, 197, 269, 297, 368, 422, 23, 60, 128, 184, 242, 334, 375, 407, 6, 110, 160, 198, 244, 320, 383, 430, 27, 78, 153, 202, 272, 322, 376, 436]
[55, 67, 167, 211, 232, 284, 363, 420, 48, 73, 136, 190, 259, 332, 351, 440, 44, 64, 142, 180, 263, 294, 361, 419, 15, 83, 157, 207, 255, 280, 350, 398]
[12, 102, 124, 199, 252, 314, 341, 432, 53, 89, 147, 170, 265, 329, 369, 409, 36, 56, 155, 206, 241, 290, 366, 441, 5, 94, 140, 223, 262, 321, 388, 394]
[1, 81, 129, 203, 227, 319, 382, 421, 43, 57, 120, 173, 233, 292, 337, 428, 8, 58, 143, 196, 267, 301, 356, 403, 34, 101, 151, 194, 230, 300, 352, 435]
[11, 74, 112, 174, 250, 316, 391, 418, 38, 72, 132, 172, 261, 310, 338, 429, 13, 66, 144, 188, 275, 299, 347, 446, 31, 71, 119, 189, 248, 304, 367, 413]
[18, 109, 123, 208, 246, 323, 355, 416, 30, 85, 126, 192, 279, 303, 378, 406, 0, 103, 149, 179, 236, 333, 357, 408, 39, 75, 139, 187, 277, 285, 339, 400]
[9, 62, 121, 193, 271, 335, 385, 412, 19, 86, 116, 217, 264, 315, 380, 411, 42, 105, 154, 222, 256, 293, 387, 439, 29, 97, 130, 212, 273, 311, 348, 417]
[35, 90, 148, 186, 231, 331, 359, 433, 45, 76, 158, 182, 253, 317, 379, 405, 46, 106, 125, 218, 237, 325, 381, 444, 40, 84, 156, 205, 251, 283, 346, 397]
[17, 95, 159, 185, 268, 281, 353, 393, 54, 61, 134, 215, 258, 318, 342, 424, 22, 100, 135, 220, 254, 306, 365, 442, 41, 91, 137, 210, 257, 288, 370, 426]
[14, 68, 141, 177, 226, 330, 374, 415, 51, 87, 113, 216, 240, 287, 354, 437, 49, 96, 115, 200, 243, 313, 336, 404, 24, 92, 131, 214, 238, 296, 386, 447]
[32, 82, 162, 219, 274, 326, 358, 396, 7, 88, 118, 176, 224, 289, 384, 402, 16, 111, 122, 213, 234, 308, 340, 425, 10, 108, 164, 183, 225, 295, 373, 410]
[20, 77, 127, 195, 266, 312, 372, 392, 33, 70, 133, 168, 276, 328, 360, 427, 26, 99, 161, 209, 278, 291, 390, 401, 21, 80, 166, 181, 235, 298, 345, 399]
[52, 107, 117, 201, 270, 302, 377, 395, 37, 93, 150, 175, 228, 282, 344, 434, 25, 69, 163, 221, 239, 305, 343, 445, 3, 59, 152, 178, 247, 309, 364, 414]
[50, 65, 138, 171, 260, 324, 371, 443, 2, 63, 146, 191, 245, 286, 389, 438, 4, 98, 145, 204, 249, 307, 362, 431, 28, 79, 165, 169, 229, 327, 349, 423]
请注意,输出列表中项目的顺序不是完全随机的,而是任何给定项目属于哪个列表。如果您希望按类别对输出中的项目进行排序,您也许可以颠倒第三步和第四步的顺序,但我认为它最终会有点尴尬,因为没有一种简单的方法可以做到这zip(it, it, it, it)
一点列表推导(我认为,您需要两个列表推导,一个用于制作迭代器,另一个用于在zip
您有名称后执行it
)。如果您需要输出列表按任何给定顺序排列,我建议使用适当的key
函数对它们中的每一个进行排序。