IndexError:列表分配索引超出范围,Python

问题描述 投票:2回答:2

我正在尝试实现功能。它的工作方式应该是这样的:

  1. 需要两个列表。
  2. 标记一些索引,最好居中。
  3. 父母双方都切换标记的索引。
  4. 其他索引按顺序转到其父元素。
  5. 如果同一父元素中已经存在相同的元素,它将映射并检查同一元素在其他父元素的位置并到达那里。
import random
def pm(indA, indB):
    size = min(len(indA), len(indB))
    c1, c2 = [0] * size, [0] * size

    # Initialize the position of each indices in the individuals
    for i in range(1,size):
        c1[indA[i]] = i
        c2[indB[i]] = i

    crosspoint1 = random.randint(0, size)
    crosspoint2 = random.randint(0, size - 1)
    if crosspoint2 >= crosspoint1:
        crosspoint2 += 1
    else:  # Swap the two cx points
        crosspoint1, crosspointt2 = crosspoint2, crosspoint1


    for i in range(crosspoint1, crosspoint2):
        # Keep track of the selected values
        temp1 = indA[i]
        temp2 = indB[i]
        # Swap the matched value
        indA[i], indA[c1[temp2]] = temp2, temp1
        indB[i], indB[c2[temp1]] = temp1, temp2
        # Position bookkeeping
        c1[temp1], c1[temp2] = c1[temp2], c1[temp1]
        c2[temp1], c2[temp2] = c2[temp2], c2[temp1]
        return indA, indB

a,b = pm([3, 4, 8, 2, 7, 1, 6, 5],[4, 2, 5, 1, 6, 8, 3, 7])

错误:

in pm
    c1[indA[i]] = i
IndexError: list assignment index out of range
python python-3.x list pycharm
2个回答
2
投票

不确定您的代码中是否还有其他错误(我没有运行它),但这是对此错误的解释。在Python(与大多数其他语言一样)中,lists(序列更精确)索引基于0]]:

>>> l = [1, 2, 3, 4, 5, 6]
>>>
>>> for e in l:
...     print(e, l.index(e))
...
1 0
2 1
3 2
4 3
5 4
6 5
>>>
>>> l[0]
1
>>> l[5]
6
>>> l[6]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

总结您的问题:

  1. 您的indA和indB列表每个都有6个元素([1..6]),它们的索引是:[[[0..5]您的
  2. c1
  3. c2列表也有6个元素(索引也为[0..5]]但是,您使用
  4. #1。
  5. 中的值作为#2。中列表的索引,而值[[6是问题,因为没有这样的索引要解决您的问题,应使用有效的索引值。要么:

  • indA和

    indB

中具有适当的值(这是我选择的值):a, b = pmxCrossover([0, 3, 1, 2, 5, 4], [4, 0, 2, 3, 5, 1])
减减
  • 1 [1

  • 任何地方,您会遇到来自indA或indB的用作索引的值:
    c1[indA[i] - 1] = i 作为一般建议:每当遇到错误时,添加

    print

    语句before错误行(从中打印(部分)内容),这可能会给您提供线索,可能导致自己解决问题。@ EDIT0发布原始代码(略有修改的版本),并进行索引转换:

    在算法之前:从每个元素中减去1以得到有效的索引

      在算法之后:加1以返回到基于1的索引
    • code00.py

    #!/usr/bin/env python3 import sys import random def pmx_crossover(ind_a, ind_b): size = min(len(ind_a), len(ind_b)) c1, c2 = [0] * size, [0] * size # Initialize the position of each indices in the individuals for i in range(1, size): c1[ind_a[i]] = i c2[ind_b[i]] = i # Choose crossover points crosspoint1 = random.randint(0, size) crosspoint2 = random.randint(0, size - 1) if crosspoint2 >= crosspoint1: crosspoint2 += 1 else: # Swap the two cx points crosspoint1, crosspointt2 = crosspoint2, crosspoint1 # Apply crossover between cx points for i in range(crosspoint1, crosspoint2): # Keep track of the selected values temp1 = ind_a[i] temp2 = ind_b[i] # Swap the matched value ind_a[i], ind_a[c1[temp2]] = temp2, temp1 ind_b[i], ind_b[c2[temp1]] = temp1, temp2 # Position bookkeeping c1[temp1], c1[temp2] = c1[temp2], c1[temp1] c2[temp1], c2[temp2] = c2[temp2], c2[temp1] return ind_a, ind_b def main(): #initial_a, initial_b = [1, 2, 3, 4, 5, 6, 7, 8], [3, 7, 5, 1, 6, 8, 2, 4] initial_a, initial_b = [1, 4, 2, 3, 6, 5], [5, 1, 3, 4, 6, 2] index_offset = 1 temp_a = [i - index_offset for i in initial_a] temp_b = [i - index_offset for i in initial_b] a, b = pmx_crossover(temp_a, temp_b) final_a = [i + index_offset for i in a] final_b = [i + index_offset for i in b] print("Initial: {0:}, {1:}".format(initial_a, initial_b)) print("Final: {0:}, {1:}".format(final_a, final_b)) if __name__ == "__main__": print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform)) main() print("\nDone.")

    输出
    (一种可能性(由于[C​​0]):]]

    random.randint

    [cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q058424002]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" code00.py Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] 64bit on win32 Initial: [1, 4, 2, 3, 6, 5], [5, 1, 3, 4, 6, 2] Final: [1, 3, 2, 4, 6, 5], [5, 1, 4, 3, 6, 2] Done. 超出范围,因为在您的c1的第四个索引中,indA [4]的值为6。而且c1索引的范围是0-5(它的长度是6)。
    使用for您尝试执行c1[indA[i]] = i

    0
    投票
    © www.soinside.com 2019 - 2024. All rights reserved.