将不同列表中的选定项目组合成一个新项目

Combining selected items from different lists into a new one

我有以下程序:

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

binary_list=[[0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1],
 [0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1],
 [0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0],
 [1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0]]

def GeneratePopulation(random_pool, binary_list):
    individual = []
    population = []
    for gene in range(0, len(binary_list)):
        gene=binary_list[gene]
        for game in range (0, len(random_pool)):
            fitness=random_pool[game][2]
            counter=random_pool[game][3]
            individual=[gene,fitness,counter]
            population.append(individual)
    return(population)

输出:

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

我的objective是将binary_list中的元素gene(二进制向量)与random_pool列表中每一项的最后两个元素结合起来,所以结果正确将是:

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

我知道循环有问题,但我已经尝试了很多东西,但我无法得到我想要的结果。谁能告诉我我做错了什么或急于解决它?

谢谢!

这是将提供预期结果的函数版本:

def GeneratePopulation(random_pool, binary_list):
    individual = []
    population = []
    for ind in range(0,len(binary_list)):
       fitness = random_pool[ind][2]
       counter = random_pool[ind][3]
       gene = binary_list[ind]
       individual=[gene,fitness,counter]
       population.append(individual)
     return(population)

在您的原始代码中,循环为 binary_list 中的每个元素迭代 random_pool - 这不是必需的,并产生了重复的结果。

请注意,变量 fitnesscounterindividual 在这里是多余的 - 您可以在不创建它们的情况下获得相同的结果。您还需要它们来做其他事情吗?

一个更 pythonic 的解决方案是 zip 列表,这样你就可以同时遍历 random_poolbinary_list 而不必使用索引.

您也可以通过以下方式解压缩池:*_, fitness, counter = pool*_ 会将第一项解包到变量 _ 中,这通常用于不需要的值,最后两项将解包到变量 fitnesscounter.

def generate_population(random_pool, binary_list):
    population = []
    for pool, gene in zip(random_pool, binary_list):
        *_, fitness, counter = pool  # Unpack the pool. Ignore the first two items.
        population.append([gene, fitness, counter])
    return population

使用 list comprehension 或生成器表达式,您可以进一步简化函数。

def generate_population(random_pool, binary_list):
    return [[gene, fitness, counter]
            for (*_, fitness, counter), gene in zip(random_pool, binary_list)]