简体   繁体   English

在循环期间从列表列表中删除元素

[英]Remove element from list of lists during loop

I have a data structure info (a list of lists?) that I am constructing as follows: 我要构造的数据结构info (列表列表?)如下:

pages     = [12, 41, 50, 111, 1021, 121]
bookCodes = ['M', 'P', 'A', 'C', 'A', 'M']
sentences = ['THISISASENTENCE',
             'ANDHEREISONEMOREEXAMP',
             'ALLFROMDIFFERENTBOOKS',
             'ANDFROMDIFFERENTPAGES',
             'MOSLTYTHESAMELENGTHS',
             'THISISSHORT'
             ]
info = list(zip(bookCodes, pages, sentences))

I am then iterating over this list (of zipped lists) on letter at a time. 然后,我一次遍历该列表(压缩列表)。 As some sentences are shorter than others (eg THISISSHORT ) I reach the final element before other sentences. 由于某些句子比其他句子短(例如THISISSHORT ),因此我在其他句子之前到达了最后一个元素。 In this case I want mask this element from future iterations completely but I don't want to filter it before I start my loop . 在这种情况下,我希望完全屏蔽以后的迭代中的该元素, 但是我不想在开始循环之前对其进行过滤

import random

letters_read = 0

for i in range(21):
    random.shuffle(info)
    for b, p, s in info:
        if len(s) <= i+1:
            print("End of sentence reached at position %s. Sentence: %s" % (i, s))
            continue    
        letters_read += 1

I am currently using continue to skip over elements where this is the case, and print a message to indicate the sentence that has reach its end. 我目前使用的continue跳过元素,其中是这样的话,并打印消息,表示已经达到它的最终判决。 However, this will continue iterating over this element until the end of the loop. 但是,这将继续在此元素上进行迭代,直到循环结束。 I want to exclude such elements from further iterations. 我想从进一步的迭代中排除这些元素。

I have ~ 10,000 sentences in my list, and these can be as large as 2000 characters, so I am assuming that by masking such sentences from future iterations rather than skipping will increase the efficiency of my script. 我的列表中有大约10,000句子,这些句子最多可以包含2000字符,因此我假设通过从以后的迭代中屏蔽此类句子(而不是跳过)将提高脚本的效率。

Is it possible to remove/mask an element from this data structure during iteration? 是否可以在迭代过程中从此数据结构中删除/屏蔽元素? I've tried using info.remove(i) and del info[i] , but this doesn't work (seeing as this is not a list). 我已经尝试使用info.remove(i)del info[i]但(因为这不是一个列表中查看),这是行不通的。


Output : 输出

End of sentence reached at position 10. Sentence: THISISSHORT
End of sentence reached at position 11. Sentence: THISISSHORT
End of sentence reached at position 12. Sentence: THISISSHORT
End of sentence reached at position 13. Sentence: THISISSHORT
End of sentence reached at position 14. Sentence: THISISASENTENCE
End of sentence reached at position 14. Sentence: THISISSHORT
End of sentence reached at position 15. Sentence: THISISSHORT
End of sentence reached at position 15. Sentence: THISISASENTENCE
End of sentence reached at position 16. Sentence: THISISASENTENCE
End of sentence reached at position 16. Sentence: THISISSHORT
End of sentence reached at position 17. Sentence: THISISASENTENCE
End of sentence reached at position 17. Sentence: THISISSHORT
End of sentence reached at position 18. Sentence: THISISASENTENCE
End of sentence reached at position 18. Sentence: THISISSHORT
End of sentence reached at position 19. Sentence: THISISASENTENCE
End of sentence reached at position 19. Sentence: MOSLTYTHESAMELENGTHS

Desired output : 所需输出


End of sentence reached at position 10. Sentence: THISISSHORT
End of sentence reached at position 14. Sentence: THISISASENTENCE
End of sentence reached at position 19. Sentence: MOSLTYTHESAMELENGTHS

You need to make copy of original list and then iterate over new copy and remove the items from original list 您需要复制原始列表,然后遍历新副本并从原始列表中删除项目

for item in list(original_list):
  ...
  original_list.remove(item)

In your case, code will look like below 就您而言,代码如下所示

total_read = 0

for i in range(21):
    random.shuffle(info)
    for index, value in enumerate(list(info)):
        b, p, s = value
        if len(s) <= i+1:
            print("Overshot! Shouldn't see this sentence anymore: %s" % (s))
            info.pop(index)
        print s[:i+1], i, s

        total_read += len(s[i + 1])

You can use del to delete the item from the zipped list 您可以使用del从压缩列表中删除项目

for i in range(21):
    q=0
    for p, b, s in info:
        if len(s)<=i+1:
            print(f'Overshot! Remove this element {s} {q}')
            del info[q]
        print(f"{s[:i+1]}, {i}, {s}")
        total_read += len(s[i+1])
        q+=1

Sanitize your input first and then loop over it: 首先清理您的输入,然后遍历它:

sentences = ['THISISASENTENCE',
             'ANDHEREISONEMOREEXAMP',
             'ALLFROMDIFFERENTBOOKS',
             'ANDFROMDIFFERENTPAGES',
             'MOSLTYTHESAMELENGTHS',
             'THISISSHORT'
             ]
max_len = len(max(sentences, key=len))  # kudos ZachGates
print max_len  # 21
sentences = filter(lambda x: len(x)==max_len, sentences)
print sentences  # ['ANDHEREISONEMOREEXAMP', 'ALLFROMDIFFERENTBOOKS', 'ANDFROMDIFFERENTPAGES']

Now you can proceed as you did. 现在,您可以像以前一样继续进行。

Make a copy of the list and iterate through the copy and delete the item from orginal. 制作列表的副本并遍历该副本,然后从原始列表中删除该项目。

for i in info[:]:
  info.remove(i)

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

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