【问题标题】:Randomly sample from arbitrarily nested lists while maintaining structure从任意嵌套列表中随机采样,同时保持结构
【发布时间】:2018-01-24 03:32:32
【问题描述】:

我正在尝试编写一个函数,该函数从任意嵌套列表中随机选择整数,同时保持列表的顺序和结构(尽管可以忽略空列表)。样本数应该从 0 到嵌套列表中的整数个数之间均匀随机。

例如,运行listrand([1,2,3,[3,4],[65,[3]]]) 3 次可能会:

[1, 3, [3], [65, [3]]]
[1, 2, [[3]]]
[[3, 4], [65]]

问题是我需要它均匀分布,所以我不能使用类似的东西

sample = [[random.sample(mylist)] for mylist in listoflists]

因为那将是二项式。

至少我需要它来处理单级嵌套。我考虑过从扁平列表中采样,但我不确定如何使用它们来构建所需的输出。

【问题讨论】:

  • 第一个输出写成[1, 3, [3], [65, [3]]]而不是[1, 3, [3], [65], [[3]]]有多重要?另外,如果要对 3 和 4 都进行采样,我们可以写[1, 3, [3], [4], [65]]吗?
  • 将抽样项目保留在其原始列表中很重要。因此,如果65list3 中并且[3]list3 中,那么输出应该在list3 的位置有[65, [3]]
  • 好的。另一个问题:你的输出有不同的长度。该函数是以一定的概率选择每个值还是以相等的概率选择一定数量的值?
  • 对不起,忘了说。样本数应从 0 到嵌套列表中的整数个数之间均匀随机。
  • 您是否缺少一组外括号?名单真的是[[1, 3, [3], [65, [3]]], [1, 2, [[3]]], [[3, 4], [65]]]吗?您想要扁平列表中的样本还是列表和整数的最顶层列表中的一个元素?

标签: python list random


【解决方案1】:

此解决方案通过构造满足您的要求。换句话说,选择的元素数量是均匀随机的。

import random
from collections import Iterable

def count(l, r=0):
    for i in l:
        if isinstance(i, Iterable):
            r += count(i)
        else:
            r += 1
    return r

def listrand(target):
    N = count(target)
    nchosen = random.randint(0, N-1)
    chosen = set(random.sample(range(N), nchosen))

    def build(l, c=0):
        output = []
        for i in l:
            if isinstance(i, Iterable):
                c, sublist = build(i, c)
                if sublist:
                    output.append(sublist)
            else:
                if c in chosen:
                    output.append(i)
                c += 1
        return c, output

    return build(target)[1]        

样本输出:

target = [1,2,3,[3,4], [65,[3]]]

for i in range(5):
    print(listrand(target))

[1, 2, 3, [3, 4], [[3]]]
[2]
[]
[2, 3, [3, 4]]
[[4]]

【讨论】:

  • 这正是我所追求的!你能解释一下为什么要添加双 def listrand() 吗?
猜你喜欢
  • 1970-01-01
  • 2017-08-28
  • 2014-02-01
  • 1970-01-01
  • 2011-09-22
  • 2018-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多