以属性为条件选择列表中的随机元素

时间:2015-11-13 14:58:16

标签: python list random

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) 
嘿那里! 所以我想从这个Agent列表中随机选择一些代理,其状态我最终会改变1.不幸的是随机选择函数在所有元素中进行选择。但是我想只选择那些状态为0的人。

如果没有创建新列表,我希望这样做。

4 个答案:

答案 0 :(得分:3)

我在这里看到3个选项:

  • 无论如何创建一个列表,您可以使用列表解析来完成:

    random.choice([a for a in agents if a.state == 0])
    
  • random.choice()调用放入循环中,继续尝试,直到找到符合条件的调用:

    while True:
        agent = random.choice(agents)
        if agent.state == 0:
            break
    
  • 索引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]
    

答案 1 :(得分:2)

我知道有四种算法。

第一部分详见this answer。遍历数组,然后如果遇到满足条件的元素,请检查随机整数是否小于(1/(however many elements you've passed that satisfy the condition))

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

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

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

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

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

同样,最后2个算法速度非常快,但要么保证不起作用,要么保证不完全随机。我不知道一种快速,保证工作,完全公平和随机的算法。

答案 2 :(得分:1)

使用numpy.where:

import numpy as np

class Agent:
    def __init__(self, state):
        self.state = state

#initialize values
state_0_agents = 10
state_1_agents = 10

#list of agents
agents = [0]*state_0_agents
agents += [1]*state_1_agents

selected_agent_idx = random.choice(np.where(np.array(agents) == 0))

答案 3 :(得分:0)

您还可以在numpy中使用nonzero函数,因为它返回一个迭代次数不为零的索引列表。然后,您可以将其与choice函数结合使用,以更改该列表的元素索引中的随机值:

import numpy as np
index_agent0 = np.nonzero(agents==0)[0]
agents[np.random.choice(index_agent0)] = 1