Python“;不在「;索引超出范围注册
我正在处理某种问题,我找不到任何解决办法。 我的问题是,如果嵌套列表中的某个值不在另一个列表中,则控制该值;如果该值不在另一个列表中,则删除该值,但在非行中,则会出现类似索引超出范围的错误Python“;不在「;索引超出范围注册,python,indexoutofrangeexception,Python,Indexoutofrangeexception,我正在处理某种问题,我找不到任何解决办法。 我的问题是,如果嵌套列表中的某个值不在另一个列表中,则控制该值;如果该值不在另一个列表中,则删除该值,但在非行中,则会出现类似索引超出范围的错误 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 wo
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:]
男子优先权示例:
[['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:
索引器:列表索引超出范围
你正在编辑你正在阅读的列表,你决不能这样做 行
men\u pref[i]=men\u pref[i][:j]+men\u pref[i][j+1::
您正在从列表中删除一个项目,但是您的
j
变量从0
到列表的原始长度,因此当您检查men\u pref[i][j]
ifj>len(men\u pref[i])时,最终会出现索引错误。
编辑:
当然,如果您想编辑当前列表,则必须使用向后索引阅读(从最后一个开始,如果不在女性列表中,则删除该列表,然后继续下一项):
另一种方法是使用列表理解:
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
]
可以将集合与列表comp一起使用,但不能对列表进行迭代和变异,因为每次删除元素时,列表都会变小,并且索引基于开始该范围时列表的大小:
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)
你是故意跳过最后一个或最后两个元素吗?你到底想实现什么?不,我只是在尝试一些东西,正如我所知-1肯定在那里,因为len()函数给出了有多少个元素的信息,我正在处理比它小1的索引。我已将-2更新为-1@PadraicCunningham例如,《绯闻女巫》不在女性名单上,我想把它从男性名单中删除,但它给了我一个“不在”的错误@E先生是的,你是对的,我的错误。对不起,好的。我已经明白了。它给出了一个错误,因为它的长度和索引当然在变化。“你绝对不能这样做”——如果你明白发生了什么,你可以很容易地做到。但在这种情况下,你是对的,这只会增加混乱。谢谢你的解决方案,因为我知道错误的原因,我可以处理它。谢谢你。如果你检查整个列表,你可以,你不应该。我还没有看到这样一种情况:它是编写代码的最佳方式。据我所知,这只是产生bug的一个原因,特别是当你在一段时间后改变了一些东西并忘记了它的时候。谢谢你,我已经理解了这个问题problem@ulmotl,不用担心,您也可以使用revered或在每个列表的末尾开始您的范围,列表与集合的比较是最有效的。谢谢。它工作得很好,因为我理解这个问题,所以您的解决方案非常有意义。
def heroes_updater(men_pref, women):
for sub in men_pref:
for m in reversed(sub):
if m not in women:
sub.remove(m)