Reputation: 679
I want to remove values from a dictionary if they contain a particular string and consequentially remove any keys that have an empty list as value.
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]
The result I want is:
{
'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/'
]
}
How can I remove all dictionary values that contain a string, and then any keys that have no values as a result?
Upvotes: 4
Views: 2383
Reputation: 10957
This is a one-liner:
{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])}
The expected output:
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/'
]
}
Upvotes: 3
Reputation: 811
There are a couple of ways you could do it. One using regex and one without.
if you're not familiar with regex you could try this:
for key, value in mydict.items():
if val in value:
mydict.pop(key)
output would be:
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/']}
Upvotes: 0
Reputation: 92854
With simple loop:
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)
The output:
{'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/']}
Upvotes: 4
Reputation: 164643
You can use a list comprehension within a dictionary comprehension. You shouldn't change the number of items in a dictionary while you iterate that dictionary.
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/': []}
If you wish to remove items with empty list values, you can in a subsequent step:
res = {k: v for k, v in res.items() if v}
Upvotes: 6
Reputation: 21709
Using dict comprehension
, you can try the following:
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/']}
Upvotes: 0