关于python:如何遍历字典以删除与字符串匹配的值?

How to loop through a dictionary to remove values that match a string?

如果值包含特定的字符串,我希望从字典中删除这些值,并随后删除任何具有空列表作为值的键。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
mydict = {
    'Getting links from: https://www.foo.com/':
    [
        '+---OK--- http://www.this.com/',
        '+---OK--- http://www.is.com/',
        '+-BROKEN- http://www.broken.com/',
        '+---OK--- http://www.set.com/',
        '+---OK--- http://www.one.com/'
    ],
    'Getting links from: https://www.bar.com/':
    [
        '+---OK--- http://www.this.com/',
        '+---OK--- http://www.is.com/',
        '+-BROKEN- http://www.broken.com/'
    ],
    'Getting links from: https://www.boo.com/':
    [
        '+---OK--- http://www.this.com/',
        '+---OK--- http://www.is.com/'
    ]
}

val ="is"

for k, v in mydict.iteritems():
   if v.contains(val):
     del mydict[v]

我想要的结果是:

1
2
3
4
5
6
7
8
9
10
11
12
{
    'Getting links from: https://www.foo.com/':
    [
        '+-BROKEN- http://www.broken.com/',
        '+---OK--- http://www.set.com/',
        '+---OK--- http://www.one.com/'
    ],
    'Getting links from: https://www.bar.com/':
    [
        '+-BROKEN- http://www.broken.com/'
    ]
}

如何删除所有包含字符串的字典值,然后删除所有没有值的键?


简单循环:

1
2
3
4
5
6
7
8
val ="is"

new_dict = dict()
for k, v in mydict.items():
    values = [i for i in v if val not in i]
    if values: new_dict[k] = values

print(new_dict)

输出:

1
{'Getting links from: https://www.foo.com/': ['+-BROKEN- http://www.broken.com/', '+---OK--- http://www.set.com/', '+---OK--- http://www.one.com/'], 'Getting links from: https://www.bar.com/': ['+-BROKEN- http://www.broken.com/']}


您可以在字典理解中使用列表理解。在迭代字典时,不应该更改字典中的项数。

1
2
3
4
5
6
7
res = {k: [x for x in v if 'is' not in x] for k, v in mydict.items()}

# {'Getting links from: https://www.foo.com/': ['+-BROKEN- http://www.broken.com/',
#                                               '+---OK--- http://www.set.com/',
#                                               '+---OK--- http://www.one.com/'],
#  'Getting links from: https://www.bar.com/': ['+-BROKEN- http://www.broken.com/'],
#  'Getting links from: https://www.boo.com/': []}

如果要删除列表值为空的项,可以在后续步骤中执行以下操作:

1
res = {k: v for k, v in res.items() if v}


这是一条单行线:

1
{k: [e for e in v if val not in e] for k, v in mydict.items() if any([val not in e for e in v])}

预期产量:

1
2
3
4
5
6
7
8
9
10
11
12
Out[1]: {
    'Getting links from: https://www.bar.com/':
    [
        '+-BROKEN- http://www.broken.com/'
    ],
    'Getting links from: https://www.foo.com/':
    [
        '+-BROKEN- http://www.broken.com/',
        '+---OK--- http://www.set.com/',
        '+---OK--- http://www.one.com/'
    ]
}


使用dict comprehension可以尝试以下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import re

val = 'is'

# step 1 - remove line having is
mydict = {k:[re.sub(r'.*is*.', '', x) for x in v] for k,v in mydict.items()}

# filtering out keys if there is no value - if needed
mydict = {k:v for k,v in mydict.items() if len(v) > 0}

print(mydict)

{'Getting links from: https://www.foo.com/': ['com/',
  'com/',
  '+-BROKEN- http://www.broken.com/',
  '+---OK--- http://www.set.com/',
  '+---OK--- http://www.one.com/'],
 'Getting links from: https://www.bar.com/': ['com/',
  'com/',
  '+-BROKEN- http://www.broken.com/'],
 'Getting links from: https://www.boo.com/': ['com/', 'com/']}

有几种方法可以做到。一个使用regex,另一个不使用regex。

如果您不熟悉regex,可以尝试以下方法:

1
2
3
for key, value in mydict.items():
    if val in value:
        mydict.pop(key)

输出为:

1
2
3
4
5
6
7
8
9
10
    mydict = {'Getting links from: https://www.bar.com/': ['+---OK--- http://www.this.com/',
  '+---OK--- http://www.is.com/',
  '+-BROKEN- http://www.broken.com/'],
 'Getting links from: https://www.boo.com/': ['+---OK--- http://www.this.com/',
  '+---OK--- http://www.is.com/'],
 'Getting links from: https://www.foo.com/': ['+---OK--- http://www.this.com/',
  '+---OK--- http://www.is.com/',
  '+-BROKEN- http://www.broken.com/',
  '+---OK--- http://www.set.com/',
  '+---OK--- http://www.one.com/']}