【问题标题】:Split number in randomly-sized portions in PythonPython中随机大小的部分拆分数字
【发布时间】:2015-05-02 16:03:09
【问题描述】:

我有x = 10y = 100

我可以在x“元素持有者”之间随机分配y元素吗?

我想创建x 类别,每个类别都有随机数量的项目;但是,创建的项目数应该正好是y

我猜是这样的

# number of categories and items
x = 10, y = 100

# keep track of how many items we have left to add
y_left = y

# create all categories
for i in range(x):
    # create category

    # find number of items in this category
    num_items_in_category = random.randint(1, y_left)

    # create items
    for j in range(num_items_in_category):
        # create item

    # set new number of items left to add
    y_left -= num_items_in_category

【问题讨论】:

  • 为什么不直接在“部分”大小的组中创建对象,为什么不在一个循环中创建所有y对象并将每个对象分配给@ 987654329@创建后立即选择?
  • 这是一个更聪明的主意。但是如何在新创建的公司中检索随机对象?
  • random.choice(items)
  • 它将在所有类别中随机出现,而不仅仅是我在同一例程中创建的类别

标签: python random random-sample


【解决方案1】:

这实际上并不太难。让我们创建我们的容器:

import random

num_containers = 10
num_objects = 100

containers = [[] for _ in range(num_containers)]
objects = (some_object() for _ in range(num_objects))
# we don't need a list of these, just have to iterate over it, so this is a genexp

for object in objects:
    random.choice(containers).append(object)

【讨论】:

    【解决方案2】:

    使用这个answer 中的函数,您可以生成一个总和为y 的x 个随机数的列表。

    遍历此列表中的项目,并从每个持有者的元素群体中做出许多随机选择(移除)。

    或者举例:

    # requires RandIntVec() & RandFloats() from linked answer
    
    # whatever population you are choosing from, example letter
    population = list('qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890')
    
    # sizes (whatever you want)
    num_of_holders = 7
    total_elements = len(population)
    
    # empty holder to put results in
    element_holder = [[] for _ in xrange(num_of_holders)]
    
    # distribute total_elements elements in randomly-sized portions among num_of_holders 'element holders' 
    random_portions_in_holder = RandIntVec(num_of_holders, total_elements, Distribution=RandFloats(num_of_holders))
    
    # assign each portion of elements to each 'holder'
    for h, portion in enumerate(random_portions_in_holder):
        for p in range(portion):
            index = random.randrange( len(population) )
            element_holder[h].append(population.pop(index))
    
    # display
    print 'Randomly-portioned elements'
    for h in element_holder:
        print h
    
    # verify
    print '\nMatch desired result?'
    print 'total_elements      :', total_elements
    print 'elements in holders :', sum([len(h) for h in element_holder])
    print 'match               :', total_elements == sum([len(h) for h in element_holder])
    

    输出

    Randomly-portioned elements
    ['M', 'N', 'f', 'V', 'v', 'h', 'i', 'H', '6', '5', 'j', '7', 'r']
    ['u', 'Z', 'C', 'I', 's', 'm', 'g', 'p', 'q', 'a', 'O', 'T', 'L']
    ['K', 'E', 'P', 'U']
    ['Y', 'D', 'A', 'l', 'J', 'R', 'b', 'c', 'z', 'F']
    ['0', '1', 'o', 'X', 'G', '4', 'W', '3', '2']
    ['d', 'Q']
    ['e', 'y', 'B', '8', 'x', 'k', 'w', 't', 'S', 'n', '9']
    
    Match desired result?
    total_elements      : 62
    elements in holders : 62
    match               : True
    

    附注复制链接函数时出现了一些缩进错误,您可能需要更正它们。 elif Distribution.lower() == 'normal':下的代码需要un-缩进1级。我提交了一个经过编辑的版本(结束批准),所以根据您复制的时间,您可能需要也可能不需要编辑。

    【讨论】:

      【解决方案3】:

      我在工作中遇到了类似的问题,用字典解决了这个问题。

      import random
      # number of categories (number of keys in the dictionary) and items (sum of all the value)
      x, y = 10, 100
      
      snpDict = {}
      i = 0
      while i < y:
          a = random.randint(0, x)
          if a in snpDict:
              snpDict[a] += 1
          else:
              snpDict[a] = 1
      
          i += 1
      

      我有大量的类别和项目,性能不好。

      【讨论】:

        猜你喜欢
        • 2013-01-13
        • 1970-01-01
        • 2018-12-06
        • 2015-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-15
        • 2018-10-28
        相关资源
        最近更新 更多