简体   繁体   English

从列表 Python 中删除特定元素

[英]Remove specific elements from list Python

I want to remove from my list every \n that is before the element 'Ecrire'.我想从我的列表中删除元素“Ecrire”之前的每个\n。 It work just for the first case and not the other cases, And I really don't understand why Here is my code:它仅适用于第一种情况,不适用于其他情况,我真的不明白为什么这是我的代码:

Corps2 = ['Debut', '\n', '\n', 'Note', ' ', '<-', ' ', 'Saisie()', ' ', '', '\n', '\n', 'Selon que\n', ' ', 'Note', ' ', '≥', ' ', '16', ' ', '', ' ', '', ' ', ':', ' ', '', '\n', '\n', 'Ecrire', ' ', "('TB')", '\n', '\n', '', ' ', 'Note', ' ', '≥', ' ', '14', ' ', '', ' ', '', ' ', ':', ' ', '', '\n', '\n', 'Ecrire', ' ', "('B')", '\n', '\n', '', ' ', 'Note', ' ', '≥', ' ', '12', ' ', '', ' ', '', ' ', ':', ' ', '', '\n', '\n', 'Ecrire', ' ', "('AB')", '\n', '\n', '', ' ', 'Note', ' ', '≥', ' ', '10', ' ', '', ' ', '', ' ', ':', ' ', '', '\n', '\n', 'Ecrire', ' ', "('Passable')", '\n', '\n', 'Sinon', ' ', ':', ' ', 'Ecrire', ' ', "('Redoublant')", '\n', '\n', 'Fin_Si']
for i in Corps2:
    if i =='Ecrire' and Corps2[Corps2.index('Ecrire')-2 :Corps2.index('Ecrire')]==['\n','\n'] :
        del Corps2[Corps2.index('Ecrire')-2 :Corps2.index('Ecrire')]

Two problems: modifying a list while iterating over it, and .index only finds the first item.两个问题:在迭代列表时修改列表,并且.index只找到第一项。

Below finds all the locations to delete, then deletes them in reverse order so the indices don't point to the wrong element, which is what happens if you delete in the forward diredction:下面找到要删除的所有位置,然后以相反的顺序删除它们,这样索引就不会指向错误的元素,如果您在正向删除时会发生这种情况:

Corps2 = ['Debut', '\n', '\n', 'Note', ' ', '<-', ' ', 'Saisie()', ' ', '', '\n', '\n', 'Selon que\n', ' ', 'Note', ' ', '≥', ' ', '16', ' ', '', ' ', '', ' ', ':', ' ', '', '\n', '\n', 'Ecrire', ' ', "('TB')", '\n', '\n', '', ' ', 'Note', ' ', '≥', ' ', '14', ' ', '', ' ', '', ' ', ':', ' ', '', '\n', '\n', 'Ecrire', ' ', "('B')", '\n', '\n', '', ' ', 'Note', ' ', '≥', ' ', '12', ' ', '', ' ', '', ' ', ':', ' ', '', '\n', '\n', 'Ecrire', ' ', "('AB')", '\n', '\n', '', ' ', 'Note', ' ', '≥', ' ', '10', ' ', '', ' ', '', ' ', ':', ' ', '', '\n', '\n', 'Ecrire', ' ', "('Passable')", '\n', '\n', 'Sinon', ' ', ':', ' ', 'Ecrire', ' ', "('Redoublant')", '\n', '\n', 'Fin_Si']
to_delete = [i for i,v in enumerate(Corps2) if v == 'Ecrire']
for i in reversed(to_delete):
    del Corps2[i-1]

Note if you process the string before tokenizing it, you could just do a .replace('\nEcrire','Ecrire') first.请注意,如果您在标记之前处理字符串,您可以先执行.replace('\nEcrire','Ecrire')

FYI, the element '≥' indicates the string was decoded incorrectly:仅供参考,元素'≥'表示字符串被错误解码:

>>> '≥'.encode('cp1252').decode('utf8')
'≥'

The index call will always return the first instance of the string. index调用将始终返回字符串的第一个实例。 This is one of those situations where yor really want to loop over the indices of the list rather than directly loop over its elements.这是您真正想要遍历列表索引而不是直接遍历其元素的情况之一。

Notice also that you can't del elements from the list you are currently traversing ;另请注意,您不能从当前正在遍历的列表中del元素 but of course, when you loop over an indirect index, you can, as long as you termrnate on any IndexError .但是当然,当您遍历间接索引时,只要您在任何IndexError上终止,就可以。

for idx in range(len(Corps2)-1):
    try:
        if Corps2[idx] == '\n' and Corps2[idx+1] == 'Ecrire:
            del Corps2[idx]
    except IndexError:
         break

Demo: https://ideone.com/LhEvUB演示: https://ideone.com/LhEvUB

You should understand how the IndexError could happen - you are shortening the list for each deleted element, and so the calculated ending index will overshoot the list's end by that many items.您应该了解IndexError是如何发生的 - 您正在缩短每个已删除元素的列表,因此计算出的结束索引将超出列表的结尾那么多项目。 Also, by lucky coincidence, we already know that the element which replaces the '\n' will never also be '\n' (namely, because it will be 'Ecrire' ) so we can conveniently avoid the required complications if this were not the case.此外,幸运的是,我们已经知道替换'\n'的元素永远不会也是'\n' (即,因为它将是'Ecrire' )所以如果不是这样,我们可以方便地避免所需的复杂性案子。

Tangentially, you should conventionally not capitalize the names of regular variables in Python;切线,您不应该按照惯例将 Python 中的常规变量的名称大写; capitalized names are usually class names.大写名称通常是 class 名称。

This single line will do the thing you need:这条线将做你需要的事情:

Corps2='|'.join(Corps2).replace('|\n|\n|Ecrire','Ecrire').split('|')

Check this out too.也检查一下。 Index changes occur whenever it deletes '\n' from array.每当它从数组中删除'\n'时,都会发生索引更改。

Corps2 = ['Debut', '\n', '\n', 'Note', ' ', '<-', ' ', 'Saisie()', ' ', '', '\n', '\n', 'Selon que\n', ' ', 'Note', ' ',
          '≥', ' ', '16', ' ', '', ' ', '', ' ', ':', ' ', '', '\n', '\n', 'Ecrire', ' ', "('TB')", '\n', '\n', '',
          ' ', 'Note', ' ', '≥', ' ', '14', ' ', '', ' ', '', ' ', ':', ' ', '', '\n', '\n', 'Ecrire', ' ', "('B')",
          '\n', '\n', '', ' ', 'Note', ' ', '≥', ' ', '12', ' ', '', ' ', '', ' ', ':', ' ', '', '\n', '\n', 'Ecrire',
          ' ', "('AB')", '\n', '\n', '', ' ', 'Note', ' ', '≥', ' ', '10', ' ', '', ' ', '', ' ', ':', ' ', '', '\n',
          '\n', 'Ecrire', ' ', "('Passable')", '\n', '\n', 'Sinon', ' ', ':', ' ', 'Ecrire', ' ', "('Redoublant')",
          '\n', '\n', 'Fin_Si']
Ecrire_count = Corps2.count("Ecrire")
for counter in range(Ecrire_count - 1):
    for i in range(len(Corps2)):
        if Corps2[i+2] == 'Ecrire' and Corps2[i+1] == '\n' and Corps2[i] == '\n':
            del Corps2[i:i+2]
            break

print(Corps2)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM