2

I have one dictionary and one string, and one function that i wanted to return "y", but for now could return "y" or "z":

import re

def find_my_keyword():
   dict_colour = {
        "x": ["back", "blue", "green"],
        "y": ["yellow", "white", "green"],
        "z": ["yellow", "white"]
        }
   str1 = "I have yellow, green and white"

   for colour, keywords in dict_colour.items():
        if all(re.search(kw, str1) for kw in keywords):
            return colour

Is there any way to add new array in my z list like not green:

"z": ["yellow", "white", =! "green"] ?

Or is any library to do exactly this function in python?

Jayanth Koushik
  • 9,476
  • 1
  • 44
  • 52
John Lapoya
  • 582
  • 1
  • 8
  • 21
  • 3
    as a commentary, you don't need `re.search`, write just `kw in str1` – user2622016 Mar 18 '14 at 10:33
  • What exactly is the goal here? There might be better ways to solve this. Are you trying to find the key that have the most matches? What if you had a string like "I have yellow and white". Should that match y, z or both? or how about "I have white and blue"? – M4rtini Mar 18 '14 at 10:42

3 Answers3

2

No, you can't change python syntax. But can get the desired result. Just adopt a convention e.g. not is represented by a ~ at the beginning of the keyword. Then you can do this:

def find_my_keyword():
   dict_colour = {
       'x': ['black', 'blue', 'green'],
       ...
       'z': ['yellow', 'white', '~green']
   }

   str1 = 'I have yellow, green, white'
   for key in dict_colour:
       if all(colour not in str1 if colour.startswith('~') else colour in str1 for colour in dict_colour[key]):
           return key
Jayanth Koushik
  • 9,476
  • 1
  • 44
  • 52
2

No. I'd recommend something like this:

...
"y": {'has':["yellow", "white", "green"], 'hasnt':[]}
"z": {'has':["yellow", "white"], 'hasnt': ["green"]}
...

for colour, keywords in dict_colour.items():
    if all(kw in str1 for kw in keywords['has']) and not any(kw in str1 for kw in keywords['hasnt']):
        return colour
user2622016
  • 6,060
  • 3
  • 32
  • 53
0

There are ways to create regex patterns that should not contain a specific word. This answer might be what you're looking for. Try replacing dict_colour with

dict_colour = {
    "x": ["back", "blue", "/^((?!green).)*$/"],
    "y": ["yellow", "white", "/^((?!green).)*$/"],
    "z": ["yellow", "white"]
    }
Community
  • 1
  • 1