【问题标题】:Nested for loop index out of range嵌套for循环索引超出范围
【发布时间】:2013-11-25 07:54:38
【问题描述】:

我想出了一个相当微不足道的问题,但由于我对 python 还很陌生,所以我暂时把头砸在桌子上。 (伤害)。虽然我相信这是一个更合乎逻辑的事情来解决...... 首先,我不得不说我正在使用适用于 Cinema 4D 的 Python SDK,所以我不得不稍微更改以下代码。但这是我试图做和挣扎的事情: 我正在尝试对一些动态生成的多边形选择进行分组(基于一些规则,不是那么重要)。 以下是它以数学方式工作的方式: 这些选择基于岛屿(意味着有几个多边形连接)。 然后,必须将这些选择分组并放入我可以使用的列表中。 任何多边形都有自己的索引,所以这个应该相当简单,但就像我之前说的,我在那里很挣扎。

主要问题很容易解释:我试图在第一个循环中访问不存在的索引,导致索引超出范围错误。我尝试先评估有效性,但没有运气。对于熟悉 Cinema 4D + Python 的人,如果有人愿意,我会提供一些原始代码。到目前为止,很糟糕。这是经过简化和改编的代码。

编辑:忘了提到导致错误的检查实际上应该只检查重复项,因此当前选择的数字将被跳过,因为它已经被处理了。由于计算量大,这是必要的。

真的希望,任何人都可以让我朝着正确的方向前进,到目前为止,这段代码是有意义的。 :)

def myFunc():

        sel = [0,1,5,12] # changes with every call of "myFunc", for example to [2,8,4,10,9,1], etc. - list alway differs in count of elements, can even be empty, groups are beeing built from these values
        all = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] # the whole set
        groups = [] # list to store indices-lists into
        indices = [] # list to store selected indices
        count = 0 # number of groups
        tmp = [] # temporary list to copy the indices list into before resetting

        for i in range(len(all)): # loop through values
            if i not in groups[count]: # that's the problematic one; this one actually should check whether "i" is already inside of any list inside the group list, error is simply that I'm trying to check a non existent value
                for index, selected in enumerate(sel): # loop through "sel" and return actual indices. "selected" determines, if "index" is selected. boolean.
                    if not selected: continue # pretty much self-explanatory
                    indices.append(index) # push selected indices to the list
                tmp = indices[:] # clone list
                groups.append(tmp) # push the previous generated list to another list to store groups into
                indices = [] # empty/reset indices-list
                count += 1 # increment count
        print groups    # debug
myFunc()

编辑:

添加第二个列表后,将由extend 填充,而不是充当计数器的append,一切都按预期工作!该列表将是一个基本列表,非常简单;)

【问题讨论】:

  • 我无法从您的描述中弄清楚您要做什么,但是在 for 循环中创建的列表根本不依赖于 i,因此您将获得相同的“内部" 一遍又一遍地列出(您显示的数据是 13 倍)。
  • 这段代码非常令人费解,我建议如果你能发布更清晰的解释来说明你想要做什么,你可能会得到一些更有用的指示。否则你可能正在寻找错误问题的解决方案......
  • 是的。抱歉这么神秘。很难用英语表达自己。我添加了一张图片:bit.ly/1a2zRWV 脚本应该确定这些组,并在运行索引时检查当前索引是否已经存在于组中。如果是这样,请移至下一个索引。希望,这更有帮助。

标签: python list for-loop indexoutofboundsexception cinema-4d


【解决方案1】:
groups[count]

当你第一次调用它时,groups 是一个空列表,count 是 0。你不能在组中访问位置 0 的东西,因为那里什么都没有!

尝试制作 groups = []groups = [[]](即,不是一个空列表,而是一个只有一个空列表的列表)。

【讨论】:

  • 是的!那是最初的问题。您的解决方案不仅解决了我的问题,而且实际上为我节省了几行代码。非常感谢汉克!
【解决方案2】:

我不确定您为什么要将空列表添加到组中。也许这样更好

if i not in groups[count]:

if not groups or i not in groups[count]:

如果您不打算将它用于其他任何事情,您也不需要复制该列表。所以你可以替换

            tmp = indices[:] # clone list
            groups.append(tmp) # push the previous generated list to another list to store groups into
            indices = [] # empty/reset indices-list

            groups.append(indices) # push the previous generated list to another list to store groups into
            indices = [] # empty/reset indices-list

您甚至可以完全删除count(您始终可以使用len(groups))。您也可以用列表理解替换内部循环

def myFunc():

    sel = [0,1,5,12] # changes with every call of "myFunc", for example to [2,8,4,10,9,1], etc. - list alway differs in count of elements, can even be empty, groups are beeing built from these values
    all = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] # the whole set
    groups = [] # list to store indices-lists into

    for i in range(len(all)): # loop through values
        if not groups or i not in groups[-1]: # look in the latest group
            indices = [idx for idx, selected in enumerate(sel) if selected]
            groups.append(indices) # push the previous generated list to another list to store groups into
    print groups    # debug

【讨论】:

  • 我相信这将是一个问题,因为“count”永远不会增加,因此它将始终为 0。
  • @RobertH.,说得好。所以最初的逻辑有点错误。我现在只是稍微重构一下
  • 啊,刚刚看到你的编辑。我以前有这样的代码,但是当附加这样的列表时,它给了我错误的结果。 (公平地说,列表是被引用的,而不是被复制的?)该列表在组列表中仍然是“活动的”,所以对它的任何更改甚至会更改任何引用的值?或者 python 在附加列表时是否以另一种方式处理这个问题?我一定会更深入地研究它! - 感谢您的意见!
  • @RobertH.当您说indices = [] 时,您正在重新绑定indices,因此此时它与之前的值分离。如果您使用indices[:] = [],您会遇到问题,因为现在您还清除了附加到组的列表的内容
  • @RobertH.当您执行indices = [] 时,它会创建一个新列表并将标签“索引”重新分配给新列表。如果“索引”指向前一个列表,则该列表将丢失该引用。
【解决方案3】:

正确的第 11 行来自:

   if i not in groups[count]

到:

   if i not in groups:

【讨论】:

  • groups 保存列表,i 是一个整数。那么这总是True..
  • 嗨。感谢您的回答。已经试过了。这无济于事,因为它会与另一个列表进行比较(请记住,列表中的列表)。所以我必须更深一层,还是我错过了什么?
  • 您可以做的是在开头添加类似 abc = 0 的内容,然后一旦将某些内容添加到列表中,使 abc = 1 并使循环工作一次 abc = 1(一旦列表不是t 空了)。在那个循环中,您可以使用您的原始代码。
猜你喜欢
  • 1970-01-01
  • 2019-04-17
  • 1970-01-01
  • 2017-08-09
  • 1970-01-01
  • 2021-09-02
  • 2020-07-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多