根据属性选择列表中的随机元素

Dio*_*Dio 3 python random list

class Agent:
    def __init__(self, state):
        self.state = state
#initialize values
state_0_agents = 10
state_1_agents = 10
numberofselections = 2 #number of agents who can choose to transition to the higher plane

#list of agents
agents = [Agent(0) for i in range(state_0_agents)]
agents.extend(Agent(1) for i in range(state_1_agents))

random.choice(agents) 
Run Code Online (Sandbox Code Playgroud)

嘿!因此,我想从此“代理”列表中随机选择几个代理,其状态最终将更改为1。不幸的是,随机选择功能会在所有元素中进行选择。但是我只想随机选择状态为0的那些。

我希望如果不创建新列表就可能发生这种情况。

Mar*_*ers 5

我在这里看到3个选项:

  • 无论如何创建列表,都可以通过列表理解来实现:

    random.choice([a for a in agents if a.state == 0])
    
    Run Code Online (Sandbox Code Playgroud)
  • random.choice()呼叫置于循环中,继续尝试直到获得符合条件的呼叫:

    while True:
        agent = random.choice(agents)
        if agent.state == 0:
            break
    
    Run Code Online (Sandbox Code Playgroud)
  • 为您的agents列表建立索引,然后从该索引中进行选择;这些实际上仍然只是列表:

    agent_states_index = {}
    for index, agent in enumerate(agents):
        agent_states_index.setdefault(agent.state, []).append(index)
    
    agent_index = random.choice(agent_states_index[0])
    agent = agents[agent_index]
    
    Run Code Online (Sandbox Code Playgroud)


che*_*esu 5

我知道有四种算法。

第一个在这个答案中有详细说明。遍历数组,然后如果遇到满足条件的元素,请检查随机整数是否小于(1/(however many elements you've passed that satisfy the condition))

第二种是遍历数组,将满足条件的新数组元素添加到新数组中,然后从该列表中随机选择一个。

这两种算法都在 O(n) 时间内运行,其中 n 是数组的大小。如果元素存在并且满足条件,则保证它们会找到元素。

还有另外两种算法要快得多。它们都在 O(1) 时间内运行,但有一些主要的弱点。

第一种是随机选择索引,直到找到满足条件的索引。这具有潜在的无限时间复杂度,但实际上是 O(1)。(如果满足条件的元素很少,而且数组很大,比如 10000 个元素中有 1 个,这会变慢。)如果元素不存在,也不能保证找到;如果没有满足条件的元素,你要么有一个无限循环,要么必须编写算法来进行有限数量的猜测,即使它存在,你也可能会错过一个元素。

第二种是随机选取一个索引,然后不断递增,直到找到满足条件的索引。保证找到一个可接受的索引或查看所有索引而不会进入无限循环。它的缺点是不完全随机。显然,如果您每次将索引增加 1,它将是非常非常非随机的(如果数组中有可接受的索引块)。但是,如果您从与数组元素数量互质的少数数字之一中随机选择增量,那么它仍然不是公平和随机的,而是相当公平和随机的,并且保证成功。

同样,这最后 2 种算法非常快,但不能保证工作或不能保证完全随机。我不知道有一种算法既快速又保证有效,而且完全公平和随机。