【问题标题】:Recursive and random grouping a list递归和随机分组列表
【发布时间】:2018-06-29 19:31:33
【问题描述】:

我正在尝试编写一个函数来创建二分法分组列表 f。前任。如果我的输入如下:

[a, b, c, d, e, f, g, h]

我想选择随机整数,它会一次又一次地递归地将其拆分为较小的子列表,直到子列表的长度最大为两个,例如:

[[a, [b, c]], [d, [[e, f], [g, h]]]]

这是我到目前为止得到的,但仍然给了我 TypeError(列表索引必须是整数或切片,而不是列表):

def split_list(l):
    if l.__len__() > 2:
        pivot = np.random.random_integers(0, l.__len__() - 1)
        print(pivot, l)
        l = [RandomTree.split_list(l[:pivot])][RandomTree.split_list(l[pivot:])]
    return l

我被困住了,我会非常感谢任何建议。

【问题讨论】:

  • RandomTree 是什么?
  • 目前还不完全清楚列表中每个总分组的长度是如何确定的。例如,列表是否应该始终以前三个项目的分组开始?如果列表的长度是 10 而不是 8 怎么办?
  • @Uriel RandomTree 只是我定义 split_list 的类。
  • @Ajax1234 不,这个分组只是一个例子。我想为每次迭代选择随机分组索引(只要子列表大于 2)。
  • 好的,鉴于有关成为班级成员的信息,我已经稍微编辑了我的答案。让我知道它是否解决了您的问题

标签: python python-3.x algorithm list recursion


【解决方案1】:

根据您的示例,这是一个不会生成单元素列表的解决方案:

import random

def splitlist(l, minlen=2):
    if len(l) <= minlen:  # if the list is 2 or smaller,
        return l if len(l) > 1 else l[0]  # return the list, or its only element
    x = random.randint(1, len(l)-1)  # choose a random split
    return [splitlist(l[:x], minlen), splitlist(l[x:], minlen)]

使用示例:

>>> splitlist(list(range(8)))
[[0, [1, [2, [3, 4]]]], [[5, 6], 7]]

【讨论】:

  • 您的解决方案正是我想要的。谢谢!
  • 您的答案与我的不同之处仅在于使用列表创建而不是串联(这增加了对一个元素列表进行冗余修复的要求)。虽然我不介意您发布它,但我看不出它是如何添加超出先前给出的答案的内容,以及为什么有必要。只是好奇。
  • 看着你的答案(没有测试过),它似乎没有涵盖单元素案例。我还发现列表创建比您的串联版本更具可读性。我想我可以在您的回答下发表我的建议作为评论。
  • 从本质上讲,它确实涵盖了一个元素的情况。再次查看递归 - 一个元素递归停止的情况返回一个连接到另一个的列表(并且两者都至少有一个元素长),因此不可能有少于 2 个元素的子列表。这就是我要注意您必须执行的修复的意思。
【解决方案2】:

您的问题对所使用的数据类型不是很清楚,并且似乎使用了一种非传统的递归类型(可能作为类的一部分)。对于错误向下滚动一点。

我冒昧地稍微修改了代码并使用了普通的random 库,所以你正在寻找的可能看起来像

import random # at the module-declaration part of your program

def split_list (l):
    if len(l) < 2:
        return l
    pivot = random.randint(1, len(l) - 1)
    return [RandomTree.split_list(l[:pivot]) + RandomTree.split_list(l[pivot:])]

我们正在停止对单个元素列表的递归,如果我们还没有停止,则进一步应用递归,使用从可能范围中提取的随机索引(请注意,random.randint 生成具有指定边界的索引 包括)。


您的错误是没有在返回值的两部分之间使用任何连接运算符。

[A][B] 不会连接两个列表,而是尝试从A 索引B(在您的情况下)中给出的列表,这是一种类型错误的用法。

因此,您可以将原始功能(已弃用的numpy随机)用作

def split_list(l):
    if l.__len__() > 2:
        pivot = np.random.random_integers(0, l.__len__() - 1)
        l = [RandomTree.split_list(l[:pivot])] + [RandomTree.split_list(l[pivot:])]
    return l

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-01
    • 1970-01-01
    相关资源
    最近更新 更多