Python:从迭代器中的列表中删除元素?

Python:从迭代器中的列表中删除元素?,python,Python,我试图从Python中的列表中删除元素。大多数答案似乎表明使用列表迭代器是最好的,但我认为这不可能(或者至少是优雅的)解决我的问题 我想遍历test\u data列表,删除满足以下两个条件的任何项目:(1)具有属性total:sum(2)具有属性(pagePath),该属性以列表中的任何元素开始,但不等于该元素mystrings 以下是我的字符串列表和测试数据: mystrings = [u'/calculate-state-pension', u'/check-uk-visa']

我试图从Python中的列表中删除元素。大多数答案似乎表明使用列表迭代器是最好的,但我认为这不可能(或者至少是优雅的)解决我的问题

我想遍历
test\u data
列表,删除满足以下两个条件的任何项目:(1)具有属性
total:sum
(2)具有属性(
pagePath
),该属性以列表中的任何元素开始,但不等于该元素
mystrings

以下是我的字符串列表和测试数据:

    mystrings = [u'/calculate-state-pension', u'/check-uk-visa']
    test_data = [
        {
            "pagePath": "/check-uk-visa",
            "total:sum": 2.0
        },
        {
            "pagePath": "/check-uk-visa/y",
            "total:sum": 3.0
        },
        {
            "pagePath": "/check-uk-visa/n",
            "total:sum": 4.0
        },
        {
            "pagePath": "/bank-holidays",
            "total:sum": 2.0
        },
        {
            "pagePath": "/check-uk-visa",
            "searchUniques:sum": 2.0
        }
    ]
因此,我想以以下列表结束:

    results = [
        {
            "pagePath": "/check-uk-visa",
            "total:sum": 2.0
        },
        {
            "pagePath": "/bank-holidays",
            "total:sum": 2.0
        },
        {
            "pagePath": "/check-uk-visa",
            "searchUniques:sum": 2.0
        }
    ]
这是我的代码:

    results = test_data[:]
    for r in results_copy:
        for s in mystrings:
            if 'total:sum' in r and r['pagePath'].startswith(s) \
                 and r['pagePath'] != s:
                results.remove(r)
    return results
但这似乎不起作用。它删除带有
/check uk visa/y
的元素,但不删除带有
/check uk visa/n
的元素


我做错了什么?我认为这与删除和迭代器有关——它看起来像是在跳过元素

您想要
任何
组合,其中
“pagePath”
值在字符串列表中以字符串开始,但不等于字符串

for dic in test_data[:]:
    s = dic.get("pagePath","")
    if "total:sum" in dic and any(s.startswith(y) and s != y  for y in mystrings):
        test_data.remove(dic)

[{'total:sum': 2.0, 'pagePath': '/check-uk-visa'}, {'total:sum': 2.0, 'pagePath': '/bank-holidays'}, {'searchUniques:sum': 2.0, 'pagePath': '/check-uk-visa'}]
一个警告是,如果您的mystrings列表中有类似的字符串,其中一个可能以相同的字母开头,但不相等,但可能相等于另一个,因此在这种情况下,我们可以使用一个集合进行0(1)查找,并在中使用

mystrings = {u'/calculate-state-pension', u'/check-uk-visa'}

for dic in test_data[:]:
    s = dic.get("pagePath","")
    if "total:sum" in dic and any(s.startswith(y) for y in mystrings)and s not in mystrings:
        test_data.remove(dic)
print(test_data)

过滤类似内容的最简单方法通常是使用
filter
功能

results_copy = filter(lambda r: ('total:sum' in r
                                 and any([r['pagePath'].startswith(s) 
                                                             for s in mystrings])
                                 and r['pagePath'] not in mystrings), 
                      results)
或者,您可以使用列表理解。有时,除了进行过滤外,还需要进行一些处理,这样更容易阅读:

results_copy = [r for r in results if ('total:sum' in r
                                       and any([r['pagePath'].startswith(s) 
                                                             for s in mystrings])
                                       and r['pagePath'] not in mystrings)]

谢谢,列表理解对于可读性来说绝对是最好的。除了这两项工作都不需要,而且你需要做两次查找而不是一次,列表比较并不总是答案。