-1

How can I refactor the code by adding a check for i["i"] not in numbers_allowed and get the expected output, I tried adding an or condition but its not giving the expected output.

alphabets_allowed = {"a", "b", "c", "*"}
numbers_allowed = {"1", "2", "3", "*"}

my_list = [
    {"i": "a", "j": "alphabet"},
    {"i": "x", "j": "alphabet"},
    {"i": "1", "j": "number"},
    {"i": "8", "j": "number"},
    {"i": "*", "j": "both"}
]

def something(i):
    i["status"] = "not alphabet or number"
    print("do something", i)
    return i

for i in my_list:
    if i["i"] not in alphabets_allowed:
        something(i)
    else:
        print("ignore", i)

Current Output

ignore {'i': 'a', 'j': 'alphabet'}
do something {'i': 'x', 'j': 'alphabet', 'status': 'not alphabet or number'}
do something {'i': '1', 'j': 'number', 'status': 'not alphabet or number'}
do something {'i': '8', 'j': 'number', 'status': 'not alphabet or number'}
ignore {'i': '*', 'j': 'both'}

Expected Output

ignore {'i': 'a', 'j': 'alphabet'}
do something {'i': 'x', 'j': 'alphabet', 'status': 'not alphabet or number'}
ignore {'i': '1', 'j': 'number'}
do something {'i': '8', 'j': 'number', 'status': 'not alphabet or number'}
ignore {'i': '*', 'j': 'both'}

Wrong Output (if I change the condition to i["i"] not in alphabets_allowed or i["i"] not in numbers_allowed)

do something {'i': 'a', 'j': 'alphabet', 'status': 'not alphabet or number'}
do something {'i': 'x', 'j': 'alphabet', 'status': 'not alphabet or number'}
do something {'i': '1', 'j': 'number', 'status': 'not alphabet or number'}
do something {'i': '8', 'j': 'number', 'status': 'not alphabet or number'}
ignore {'i': '*', 'j': 'both'}
Alc
  • 93
  • 4
  • are you sure you didn't mean: `i["i"] not in alphabets_allowed and i["i"] not in numbers_allowed` ? – ajoseps Aug 01 '22 at 18:19
  • "Wrong Output (if I change the condition to `i["i"] not in alphabets_allowed or i["i"] not in numbers_allowed`)" This is because you should use `and` rather than `or` to combine the conditions. Please see the linked duplicate to understand this common logic error. Short version, in English: "Neither X nor Y" means the same thing as "Not X, and also not Y". It **does not** mean the same thing as "Either non-X, or non-Y". – Karl Knechtel Aug 01 '22 at 18:21

1 Answers1

2

hope I'm understanding the ask correctly, but you can use set.union to merge both sets into one, and then use that instead. The rest of the code stays the same from what you had above.

alphabets_allowed = {"a", "b", "c", "*"}
numbers_allowed = {"1", "2", "3", "*"}

all_allowed = alphabets_allowed | numbers_allowed

for i in my_list:
    if i["i"] not in all_allowed:
        ...

Outputs

ignore {'i': 'a', 'j': 'alphabet'}
do something {'i': 'x', 'j': 'alphabet', 'status': 'not alphabet or number'}
ignore {'i': '1', 'j': 'number'}
do something {'i': '8', 'j': 'number', 'status': 'not alphabet or number'}
ignore {'i': '*', 'j': 'both'}
rv.kvetch
  • 9,940
  • 3
  • 24
  • 53
  • 1
    thanks for the reply, I have upvoted your answer, but the question linked explain the mistake – Alc Aug 01 '22 at 18:30
  • fair enough, and yeah based on the comments looks like that could indeed be the issue in this case. – rv.kvetch Aug 01 '22 at 18:33