#python #generator
#python #генератор
Вопрос:
Первый вопрос по StackExchange… Я изучаю Python для выполнения некоторого анализа текста в течение нескольких месяцев, запустив Python 3.5 на Mac, и у меня возникла проблема с некоторым кодом, который выглядит следующим образом:
from Levenshtein import distance
keywords = ['some', 'list']
line = 'some long string.'
for w in line.split():
if condition_1 and not any(distance(w, k) < 2 for k in keywords):
do_something
elif condition_1 and any(distance(w, k) < 2 for k in keywords):
do_something_else
elif condition_2 and not any(distance(w, k) < 2 for k in keywords):
do_a_third_thing
else:
do_somthing_completely_different
Когда цикл запускается, condition_1
и condition_2
являются False
, поэтому я бы ожидал, что первая итерация цикла перейдет к четвертому варианту и сделает это. Но вместо этого, когда он проверяет третий случай, он выдает следующее сообщение об ошибке:
TypeError: distance expected two Strings or two Unicodes
Если я перейду к этой строке в отладчике и проверю тип w
и элементы keywords
списка, они все str
. Если я попытаюсь просто запустить проблемную команду в отладчике, я получу NameError:
(Pdb) any(distance(w, k) < 2 for k in keywords)
*** NameError: name 'w' is not defined
Если вместо этого я введу литерал, присвоенный w
, все в порядке:
(Pdb) any(distance('some', k) < 2 for k in keywords)
True
Что заставляет меня думать, что это как-то связано с тем, как функция generator обрабатывает пространства имен, но я не уверен. Я попытался заменить встроенную функцию на distance(w, k)
, например len(w k)
, просто для проверки, и я получаю тот же набор ошибок. Я нахожу ошибку особенно запутанной, поскольку, похоже, нет проблем с проверкой первых двух случаев.
Я мог бы предложить обходной путь, но я хотел бы знать, что здесь на самом деле происходит. Google и StackExchange пока не принесли мне радости по этой теме. Любые мысли или предложения будут приняты с благодарностью.
Ответ №1:
вы могли бы сделать это намного проще, переформатировав свои операторы if внутри цикла и проверив тип W следующим образом:
print(" W contains '{}' and is a {} ".format(w, type(w)))
assert w,str
if condition_1:
result = any(distance(w, k) < 2 for k in keywords):
print(" Result contains '{}' and is a {} ".format(result,type(result)
if result:
do_something
else:
do_something_else
elif condition_2:
if not any(distance(w,k) < 2 for k in keywords):
do_a_third_thing
else:
do_something_completely_different
Я предполагаю, что вы получаете эти ошибки, работающие с другой строкой, чем в примере. Вы проверили, что оно действительно имеет значение, прежде чем разделить его?
Комментарии:
1. Да, строка в моем коде намного длиннее, чем в примере, который я привел. Я проверил, что у нее есть значение, и когда я вставляю точку останова в строку, где я получаю ошибку, и проверяю мое пространство имен, переменная w действительно является строкой.