首页 > 解决方案 > 我忘记的简单循环错误

问题描述

我想建立一个列表。该列表具有用户要求的值的数量,并且无法通过限制且无法重复,但我不知道我的错误在哪里。该程序不会按照我想要的方式构建列表。解释起来有点难,自己用属性运行代码:

class Mundo:
    def __init__(self):
        self.existValues = list()
        self.world = self.grid()
        self.blues = self.blue()
        print(f"Map: {self.world}\n"
              f"Exist Values: {self.existValues}\n"
              f"Blue values: {self.blues}")
        # self.theArray = [[self.world, ], [self.world, ]]

    def grid(self):
        while True:
            self.size = input("Size of Map: ")
            if self.size.isnumeric() and int(self.size) >= 2:
                self.size = int(self.size)
                intSize = self.size * self.size
                mapH = list()
                gridMap = list()
                for elementos in range(1, intSize + 1):
                    if len(mapH) == self.size - 1:
                        mapH.append(elementos)
                        gridMap.append(mapH)
                        mapH = []
                    else:
                        mapH.append(elementos)
                return gridMap

    def blue(self):
        while True:
            try:
                qt = int(input("How many blues to spawn?"))
            except ValueError:
                continue
            posBlue = list()
            controle = list()
            control = False
            for _ in range(qt):
                while not control:
                    x = rint(1, self.size)
                    y = rint(1, self.size)
                    controle.append([x, y])
                    for elements in controle:
                        if elements in self.existValues:
                            control = True
                        else:
                            posBlue.append([x, y])
                            self.existValues.append([x, y])
                            control = False

            return posBlue

如果我运行代码(即 qt == 2 和 self.size == 4 ),代码的一、二或三倍会输出一个包含 3 或 2 个值的列表,有时是 4 个。

我会跑3次来展示。

输出 1: 只有 3 个蓝色值,我要求 4 个。

输出 2: 只有 2 个,我要 4 个。

输出 3: 再次。

我需要用户要求的输出。

标签: pythonarraysfor-loop

解决方案


这是您的更多 MRE 形式的代码:

from random import randint


def blue(qt: int, size: int):
    existValues = []
    posBlue = list()
    controle = list()
    for _ in range(qt):
        x = randint(1, 4)
        y = randint(1, 4)
        controle.append([x, y])
        for elements in controle:
            if elements in existValues:
                continue
            else:
                posBlue.append([x, y])
                existValues.append([x, y])

    return posBlue


print(len(blue(2, 4)))    # prints 2 because odds are good of getting 2 uniques
print(len(blue(10, 4)))   # prints 8 because it missed some
print(len(blue(100, 4)))  # prints 16 because that's the maximum number

通过使用不同的数量进行测试,很容易看出问题出在哪里——您依赖随机机会来生成独特的组合,因此不能保证循环的每次迭代for都会找到尚未找到的组合存在。

执行此操作的简单方法是生成详尽的组合列表,然后随机选择它们:

from itertools import product
from random import sample


def blue(qt: int, size: int):
    possibilities = list(product(range(1, size+1), range(1, size+1)))
    return sample(possibilities, qt)


print(len(blue(2, 4)))    # prints 2
print(len(blue(10, 4)))   # prints 10
print(len(blue(100, 4)))  # ValueError: Sample larger than population

qt请注意,如果大于 ,则会引发异常size^2。您可以决定是否要以不同的方式处理这个问题——也许给定足够多的重复次数是可以接受的?这里有一个简单的方法来解决这个问题:乘以possibilities必要的数量,以确保它至少与qt.

def blue(qt: int, size: int):
    possibilities = list(product(range(1, size+1), range(1, size+1)))
    possibilities *= 1 + (qt - 1) // len(possibilities)
    return sample(possibilities, qt)

推荐阅读