Lets say I have a dict:
d = {'AA': 'BB', 'BB': None}
And this for comprehension:
[v for t in u'{}'.format(v.lower()) for k, v in d.items()]
Its obvious that its going to fail with 'NoneType' object has no attribute 'lower', so lets try this one:
[v for t in u'{}'.format(v.lower()) for k, v in d.items() if v is not None]
The same happens!, Why? If I add another guard:
[v for t in u'{}'.format(v.lower()) if v is not None for k, v in d.items() if v is not None]
Same thing.
Why is v.lower() being called even with the guards?
However, this works:
for k,v in d.items():
if v is not None:
[v for t in u'{}'.format(v.lower())]
Update
This is the actual code that is giving me the problem, The above code was to simplify the example, but given that the answer provided below, I think I will post the actual code:
x = {'A': 'This is a Line to Be tokenized'}
for k,v in x.items():
if v is not None:
pat = [{'LOWER': str(t)} for t in tokenizer(u'{}'.format(v.lower()))]
This generate patters for Spacy, in this format:
[{'LOWER': 'this'},
{'LOWER': 'is'},
{'LOWER': 'a'},
{'LOWER': 'line'},
{'LOWER': 'to'},
{'LOWER': 'be'},
{'LOWER': 'tokenized'}]
So, originally my for comprehension to generate that output is
[{'LOWER': str(t)} for k, v in x.items() if v is not None for t in tokenizer(u'{}'.format(v))]
But, as mentioned above, when the value of the dictionary is None, it fails even when a guard is provided.
Update 2
Here are more examples:
x = {'A': 'This is a Line to Be tokenized', 'B': 'Hello'}
for k,v in x.items():
if v is not None:
pat = [{'LOWER': str(t)} for t in tokenizer(u'{}'.format(v.lower()))]
print(pat)
# [{'LOWER': 'this'}, {'LOWER': 'is'}, {'LOWER': 'a'}, {'LOWER': 'line'}, {'LOWER': 'to'}, {'LOWER': 'be'}, {'LOWER': 'tokenized'}]
# [{'LOWER': 'hello'}]
So, basically I want to convert that loop into a comprehension.