循环期间删除列表中的项目

时间:2017-04-11 23:27:39

标签: python string list split

我有以下代码。我正尝试从列表predict stringstest strings中移除两个字符串,如果在另一个中找到其中一个字符串。问题是我必须拆开它们中的每一个并检查另一个字符串中是否存在一个字符串的“部分”。如果有,那么我只是说有一个匹配,然后从列表中删除这两个字符串,以便它们不再迭代。

ValueError: list.remove(x): x not in list

我得到了上面的错误,我假设这是因为我无法从test_strings中删除字符串,因为它正在迭代?有没有解决的办法?

由于

    for test_string in test_strings[:]:
        for predict_string in predict_strings[:]:
            split_string = predict_string.split('/')
            for string in split_string:
                if (split_string in test_string):
                    no_matches = no_matches + 1
                    # Found match so remove both
                    test_strings.remove(test_string)
                    predict_strings.remove(predict_string)

示例输入:

test_strings = ['hello/there', 'what/is/up', 'yo/do/di/doodle', 'ding/dong/darn']
predict_strings =['hello/there/mister', 'interesting/what/that/is']

所以我希望hello / there和hello / there / mister之间有匹配,并且在进行下一次比较时将它们从列表中删除。

经过一次迭代,我希望它是:

test_strings == ['what/is/up', 'yo/do/di/doodle', 'ding/dong/darn']
predict_strings == ['interesting/what/that/is']

在第二次迭代之后,我希望它是:

test_strings == ['yo/do/di/doodle', 'ding/dong/darn']
predict_strings == []

2 个答案:

答案 0 :(得分:1)

当你迭代迭代时,你永远不应该尝试修改它,这仍然是你正在尝试做的事情。设置set以跟踪您的匹配,然后在结尾处删除这些元素。

此外,您的专线for string in split_string:并未真正做任何事情。您未使用变量string。要么删除该循环,要么更改代码以便您使用string

您可以使用扩充分配来增加no_matches的值。

no_matches = 0

found_in_test = set()
found_in_predict = set()

for test_string in test_strings:
    test_set = set(test_string.split("/"))
    for predict_string in predict_strings:
        split_strings = set(predict_string.split("/"))
        if not split_strings.isdisjoint(test_set):
            no_matches += 1
            found_in_test.add(test_string)
            found_in_predict.add(predict_string)

for element in found_in_test:
    test_strings.remove(element)

for element in found_in_predict:
    predict_strings.remove(element)

答案 1 :(得分:0)

从您的代码中,似乎有两个split_string匹配相同的test_string。第一次通过循环删除test_string,第二次尝试这样做但不能,因为它已被删除!

如果发现匹配,您可以尝试break内部for循环,或者使用any代替。{/ p>

for test_string, predict_string in itertools.product(test_strings[:], predict_strings[:]):
    if any(s in test_string for s in predict_string.split('/')):
        no_matches += 1  # isn't this counter-intuitive?
        test_strings.remove(test_string)
        predict_strings.remove(predict_string)