2

I have a dictionary that contains strings as keys and lists as values.

I'd like to remove all list elements that contain the strings "food", "staging", "msatl" and "azeus". I have the below code already, but am having a hard time applying the logic I have in filterIP to the rest of the strings I have.

    def filterIP(fullList):
       regexIP = re.compile(r'\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}$')
       return filter(lambda i: not regexIP.search(i), fullList)

    groups = {key : [domain.replace('fake.com', 'env.fake.com')
      for domain in filterIP(list(set(items)))]
        for (key, items) in groups.iteritems() }

    for key, value in groups.iteritems():
      value.sort()

    meta = { "_meta" : { "hostvars" : hostvars } }
    groups.update(meta)

    print(self.json_format_dict(groups, pretty=True))

Example of current output

 "role_thumper": [
    "thumper-msatl1-prod-1.env.fake.com",
    "thumper-msatl1-prod-2.env.fake.com",
    "thumper-rwva1-prod-1.env.fake.com",
    "thumper-rwva1-prod-2.env.fake.com",
    "thumper-rwva1-prod-3.env.fake.com",
    "thumper-rwva1-prod-4.env.fake.com",
    "thumper-rwva1-prod-5.env.fake.com",
    "thumper-rwva1-prod-6.env.fake.com",
    "thumper-staging-1.env.fake.com"
  ],
  "role_thumper_mongo": [
    "thumper-mongo-staging-1.env.fake.com",
    "thumper-mongo-staging-2.env.fake.com",
    "thumpermongo-rwva1-staging-1.env.fake.com",
    "thumpermongo-rwva1-staging-2.env.fake.com"
  ],
  "role_thumper_mongo_arb": [
    "thumper-mongo-arb-staging-1.env.fake.com",
    "thumpermongo-arb-rwva1-staging-1.env.fake.com"
  ],

3 Answers 3

5

A list comprehension is what you're after

x= ["a", "b", "aa", "aba"]
x_filtered = [i for i in x if "a" not in i]
print(x_filtered)
>>> ['b']

This is just shorthand for a for loop.

x_filtered = []
for i in x:
    if "a" not in i:
        x_filtered.append(i)
Sign up to request clarification or add additional context in comments.

Comments

1

A simple way to accomplish your task would be to iterate over each lists in the dictionary. Create new lists based upon your criteria, and assign the new lists to the same keys but in a new dictionary. Here is how that would look like in code:

def filter_words(groups, words):
    d = {}
    for key, domains in groups.iteritems():
        new_domains = []
        for domain in domains:
            if not any(word in domain for word in words):
                new_domains.append(domain)
        d[key] = new_domains
    return d

And you would call it like so:

groups = filter_words(groups, {"food", "staging", "msatl" and "azeus"})

The "meat" of the code above is the second for loop:

for domain in domains:
    if not any(word in domain for word in words):
        new_domains.append(domain)

This code goes over each string in the current key's list, and filters out all invalid strings according to a list of invalid words.

2 Comments

Works well! That's a really good explanation of how it works too. Your example incorrectly has new_domain rather than new_domains in the second and third to last lines. But works great otherwise. Thanks!
@Brando__ Opps. Thanks for the heads up ;-)
1

If I understand you correctly, this might help.

Set up an exclude list:

exclude=  ["food", "staging", "msatl", "azeus"]

Test list ( I couldn't really find instances in your examples)

test= ["food", "staging", "msatl", "azeus", "a", "bstaging"]

Run list comprehension (the name of iterators don't matter, you can pick more appropriate ones)

result= [i for i in test if not any([e for e in exclude if e in i])]

result ['a']

The answer above by @Julian gives a good explanation of what list comprehensions do. This uses two of them, the any part is True if there is any match in the exclude list.
Hope this helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.