python-生成非重复随机数对

python-生成非重复随机数对,python,Python,我试图生成随机数对,将对象放置在网格中的随机位置。我试着寻找答案,但我没有找到一个适合我需要的答案。我不希望这对对象重复,但它们仍然可以放在同一行或同一列中。此外,网格的大小和对象的数量由用户输入 def create_bombs(self): bombs_flaged = 0 #creates the bombs for i in range(self.bomb_num): bomb_row = randint(0,self.board_size -

我试图生成随机数对,将对象放置在网格中的随机位置。我试着寻找答案,但我没有找到一个适合我需要的答案。我不希望这对对象重复,但它们仍然可以放在同一行或同一列中。此外,网格的大小和对象的数量由用户输入

def create_bombs(self):
    bombs_flaged = 0
    #creates the bombs 
    for i in range(self.bomb_num):
        bomb_row = randint(0,self.board_size - 1)
        bomb_col = randint(1,self.board_size)
        self.bomb_list.append(Bomb(bomb_row, bomb_col, self, bombs_flaged))

考虑这一点的一种方法是:在您的情况下,有X*Y个可能的位置,特别是board_size*board_size,您希望从这些位置中选择N个self.bomb_num随机样本,不重复

random模块中的函数完美地实现了这一点:

possible_coordinates = [(x, y) for x in range(X) for y in range(1, Y+1)]
bomb_coordinates = random.sample(possible_coordinates, N)

创建该列表有点浪费,但考虑到board_size可能很小,比如30个元素,900个元素的临时列表不值得担心。

考虑这一点的一种方法是:在您的情况下,有X*Y可能的位置,特别是board_size*board_size,你想从这些位置随机抽取N个self.bomb_num样本,不重复

random模块中的函数完美地实现了这一点:

possible_coordinates = [(x, y) for x in range(X) for y in range(1, Y+1)]
bomb_coordinates = random.sample(possible_coordinates, N)
创建该列表有点浪费,但考虑到board_的大小可能很小,比如30个,一个包含900个元素的临时列表就不值得担心了。

Python的集合正是为了满足您的需要:成员资格测试非常快,时间不变:

def create_bombs(self):
    bombs_flagged = 0
    existing_bomb_coords = set()  # All bomb coordinates so far
    # Creates the bombs 
    while len(existing_bomb_coords) < self.bomb_num:  # Looping as much as needed
        bomb_row = randint(0, self.board_size-1)
        bomb_col = randint(1, self.board_size)
        bomb_coords = (bomb_row, bomb_col)
        if bomb_coords not in existing_bomb_coords:  # Very fast test
            self.bomb_list.append(Bomb(bomb_row, bomb_col, self, bombs_flagged))
            existing_bomb_coords.add(bomb_coords)  # New bomb registration
现在,我也喜欢@abarnert的答案:正如他所指出的,这有点浪费,但它非常易读。

Python的集合就是为了满足您的需要:成员资格测试非常快,时间固定:

def create_bombs(self):
    bombs_flagged = 0
    existing_bomb_coords = set()  # All bomb coordinates so far
    # Creates the bombs 
    while len(existing_bomb_coords) < self.bomb_num:  # Looping as much as needed
        bomb_row = randint(0, self.board_size-1)
        bomb_col = randint(1, self.board_size)
        bomb_coords = (bomb_row, bomb_col)
        if bomb_coords not in existing_bomb_coords:  # Very fast test
            self.bomb_list.append(Bomb(bomb_row, bomb_col, self, bombs_flagged))
            existing_bomb_coords.add(bomb_coords)  # New bomb registration

现在,我也喜欢@abarnert的答案:正如他所说,这有点浪费,但它非常清晰。

假设您的列表不小,可能包含超过1000000个坐标,有没有一种方法可以在不生成100万成员列表的情况下以同样的方式进行采样?假设您的列表不小,并且可能构成>1000000个坐标,有没有一种方法可以在不生成100万成员列表的情况下以同样的方式进行采样?