Список охранников игнорируется - PullRequest
4 голосов
/ 06 июня 2019

Допустим, у меня есть dict:

d = {'AA': 'BB', 'BB': None}

И это for comprehension:

[v for t in u'{}'.format(v.lower()) for k, v in d.items()]

Очевидно, что оно потерпит неудачу с 'NoneType' object has no attribute 'lower', поэтому давайтепопробуйте это:

[v for t in u'{}'.format(v.lower()) for k, v in d.items() if v is not None]

То же самое происходит! Почему?Если я добавлю еще один охранник:

[v for t in u'{}'.format(v.lower()) if v is not None for k, v in d.items() if v is not None]

То же самое.

Почему v.lower() вызывается даже с охранниками?

Однако это работает:

for k,v in d.items():
    if v is not None:
        [v for t in u'{}'.format(v.lower())]

Обновление

Это действительный кодЭто вызывает у меня проблему. Приведенный выше код должен был упростить пример, но, учитывая ответ, приведенный ниже, я думаю, что я опубликую фактический код:

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()))]

Это генерирует шаблоны для Spacy, в этомформат:

[{'LOWER': 'this'},
 {'LOWER': 'is'},
 {'LOWER': 'a'},
 {'LOWER': 'line'},
 {'LOWER': 'to'},
 {'LOWER': 'be'},
 {'LOWER': 'tokenized'}]

Итак, первоначально для понимания, чтобы сгенерировать этот вывод, было

[{'LOWER': str(t)} for k, v in x.items() if v is not None for t in tokenizer(u'{}'.format(v))]

Но, как уже упоминалось выше, когда value словаря равно None,он терпит неудачу, даже если предоставляется guard.

Обновление 2

Вот еще несколько примеров:

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'}]

Итак, в основном я хочу преобразовать этот цикл впонимание.

Ответы [ 2 ]

3 голосов
/ 06 июня 2019

Вам необходимо изменить порядок for s и if s:

>>> [v for k, v in d.items() if v is not None for t in u'{}'.format(v.lower())]
['BB', 'BB']
>>> 
  • . if оператор должен находиться перед тем местом, где он собираетсявызвать ошибку.

  • Второй цикл for должен быть после цикла for, который содержит итераторы, используемые вторым циклом for.

1 голос
/ 06 июня 2019

Это может быть записано следующим образом:

x = {'A': 'This is a Line to Be tokenized', 'B':None}
for k,v in x.items():
    if v is not None:
        pat = [{'LOWER': str(t)} for t in tokenizer(u'{}'.format(v.lower()))]


res = [[{'LOWER': str(t)} for t in tokenizer(u'{}'.format(v.lower()))] for k, v in x.items() if v is not None]

Вывод:

[[{'LOWER': 'this'},
  {'LOWER': 'is'},
  {'LOWER': 'a'},
  {'LOWER': 'line'},
  {'LOWER': 'to'},
  {'LOWER': 'be'},
  {'LOWER': 'tokenized'}]]

Однако, на этом этапе вы не получите много, записав его в одну строку,но потерять много с точки зрения читабельности.Я бы посоветовал вам не писать это в одной строке.

...