Python "not in" 索引超出范围错误

Python "not in" index out of range enrror

我正在处理某种问题,但找不到任何解决方案。 我的问题是我正在控制一个嵌套列表中的值,如果它不在另一个列表中,如果它不存在但不在行中,它会给我一个错误,如索引超出范围。

def heroes_updater(men_pref,women):
   for i in range(0,len(men_pref)-1):
      for j in range(0,len(men_pref[i])-1):
          if men_pref[i][j] not in women:
              men_pref[i]=men_pref[i][:j]+men_pref[i][j+1:]

示例men_pref:

[['Storm', 'Black Widow', 'Scarlet Witch', 'Rouge', 'Mystique', 'Jean Grey', 'Ms. Marvel', 'Gamora', 'Invisible Woman', 'Elektra'], ['Storm', 'Elektra', 'Jean Grey', 'Scarlet Witch', 'Mystique', 'Ms. Marvel', 'Gamora', 'Rouge', 'Black Widow', 'Invisible Woman'], ['Invisible Woman', 'Scarlet Witch', 'Mystique', 'Black Widow', 'Ms. Marvel', 'Elektra', 'Jean Grey', 'Gamora', 'Storm', 'Rouge']]

女性示例:

['Jean Grey', 'Elektra', 'Mystique', 'Ms. Marvel', 'Rouge']

错误是:

if men_pref[i][j] not in women:

IndexError: list index out of range

您正在编辑正在阅读的列表,切勿那样做。

与行 men_pref[i]=men_pref[i][:j]+men_pref[i][j+1:]
您正在从列表 men_pref[i] 中删除一个项目,但是您的 j 变量从 0 变为列表的原始长度,因此当您检查时最终会出现索引错误对于 men_pref[i][j] 如果 j>len(men_pref[i])

编辑: 的,如果你想编辑你当前的列表,那么你将不得不用一个向后的索引来阅读它(你从最后一个开始,如果它不在女性列表中,你删除它然后继续下一个项目) :

def heroes_updater(men_pref,women):
    for i in range(len(men_pref)-1, -1,-1):
        for j in range(len(men_pref[i])-1, -1, -1):
            if men_pref[i][j] not in women:
                men_pref[i].pop(j)
                # An alternative: del(mem_pref[i][j])

另一种方法是使用列表理解:

def heroes_updater(men_pref,women):
    for i in range(len(men_pref)-1, -1,-1):
        mem_pref[i] = [_w_ for _w_ in mem_pref[i] if _w_ in women]

还有其他选择,但我会留给你。 这就是你的学习方式。

通过从列表中删除元素,列表会变短 j 比列表的长度更长。要避免此问题,请不要更改列表,而是创建一个新列表:

def heroes_updater(men_pref,women):
   result = []
   for prefs in men_pref:
      new_prefs = []
      for pref in prefs:
          if pref in women:
              new_prefs.append(pref)
      result.append(new_prefs)
   men_pref[:] = result

或更好:

def filter_non_heroes(men_pref,women):
    return [
        [pref for pref in prefs if pref in women]
        for prefs in men_pref
    ]

您可以将集合与列表组合一起使用,您不能迭代和改变列表,因为每次删除一个元素时,列表都会变小,并且您的索引基于开始时列表的大小范围:

men = [['Storm', 'Black Widow', 'Scarlet Witch', 'Rouge', 'Mystique', 'Jean Grey', 'Ms. Marvel', 'Gamora', 'Invisible Woman', 'Elektra'], ['Storm', 'Elektra', 'Jean Grey', 'Scarlet Witch', 'Mystique', 'Ms. Marvel', 'Gamora', 'Rouge', 'Black Widow', 'Invisible Woman'], ['Invisible Woman', 'Scarlet Witch', 'Mystique', 'Black Widow', 'Ms. Marvel', 'Elektra', 'Jean Grey', 'Gamora', 'Storm', 'Rouge']]

wom = {'Jean Grey', 'Elektra', 'Mystique', 'Ms. Marvel', 'Rouge'}

men[:] = [[ele for ele in sub if ele in wom] for sub in men]

print(men)

或者在功能上,如果顺序无关紧要:

men = [['Storm', 'Black Widow', 'Scarlet Witch', 'Rouge', 'Mystique', 'Jean Grey', 'Ms. Marvel', 'Gamora', 'Invisible Woman', 'Elektra'], ['Storm', 'Elektra', 'Jean Grey', 'Scarlet Witch', 'Mystique', 'Ms. Marvel', 'Gamora', 'Rouge', 'Black Widow', 'Invisible Woman'], ['Invisible Woman', 'Scarlet Witch', 'Mystique', 'Black Widow', 'Ms. Marvel', 'Elektra', 'Jean Grey', 'Gamora', 'Storm', 'Rouge']]

wom = {'Jean Grey', 'Elektra', 'Mystique', 'Ms. Marvel', 'Rouge'}

men[:] = map(list,map(wom.intersection, men))

print(men)

您也可以从列表的末尾开始,使用您的范围逻辑但使用 range(len(sub)-1,-1, -1) 但仅使用反向并迭代元素本身更容易:

def heroes_updater(men_pref, women):
    for sub in men_pref:
        for m in reversed(sub):
            if m not in women:
                sub.remove(m)