2016-07-27 2 views
0

Я буду вводить большой набор данных strs для сравнения с dict со списками. Например, ул 'кандидатской степени будет сравниваться с STRs от этого Словарестрока по сравнению с списком в dict

edu_options = {'Completed College' : [ 'bachelor', 'ba', 'be', 'bs'....], 
        'Grad School' : ['phd','doctor'...] } 

вход ул поступает из edu_dict

edu_dict = { 
     "A.S":"Attended Vocational/Technical", 
     "AS":"Attended Vocational/Technical", 
     "AS,":"Attended Vocational/Technical", 
     "ASS,":"Attended Vocational/Technical", 
     "Associate":"Attended Vocational/Technical", 
     "Associate of Arts (A.A.),":"Attended Vocational/Technical", 
     "Associate of Arts and Sciences (AAS)":"Attended Vocational/Technical", 
     "B-Arch":"Completed College", 
     "B-Tech":"Attended Vocational/Technical", 
     "B.A. B.S":"Completed College", 
     "B.A.,":"Completed College", 
     "B.Arch,":"Completed College", 
     "B.S":"Completed College", 
     "B.S.":"Completed College", 
     "B.S. in Management":"Completed College", 
     "B.S.,":"Completed College", 
     "BA":"Completed College",... 
    *The list is 169 items similar to this* 
    } 

clean_edu() принимает ключ от edu_dict, удаляет знаки препинания, пробелы. ..и т.д. Например, «P.H.D.» становится «phd». Если «phd» соответствует str из любого из этих списков, он должен вернуть правильный ключ, в данном случае «Completed Graduate». Для большинства входных данных, которые я вложил, возвращается правильное значение.

def clean_edu(edu_entry): 

    lower_case_key = edu_entry.lower() # changing the key to lower case 

    chars_in = "-.,')("   #setting the chars to be translated 
    chars_out = "  " 
    char_change = "".maketrans(chars_in, chars_out)  # replacing punctuation(char_in) with empty space(char_out) 

    clean = lower_case_key.translate(char_change)  #executing char_change 


    cleaned_string = re.sub(r'\s\s{0,}','',clean).strip() 


    return cleaned_string 


while user == "": 
    for edu_level in edu_options: 
     for option in edu_options[edu_level]: 
      if option in cleaned_string: 
       user = edu_level 
       return user 

    user = "No match" 

Проблема в том, что «bs» правильно срабатывает для некоторых входов, но не для других. Когда я печатаю непревзойденную строку и их сравнение

print ("Not Detected. Adding to txt" + '\t' + edu_entry + '\t' + cleaned_string + '\t' + option) 

Output: " Not Detected. Adding to txt  business  nursing 

где bs - это вход, а l - сравнительная строка. В edu_options dict нет значения 'l', поэтому я не понимаю, откуда это происходит. Эта проблема не возникала для входных strs, таких как «bs biology» или «bs business».

Успешный запуск:

вход ул: «PHD» выход: «Завершена Высшая школа»

+1

Я думаю, что вы хотите 'для опции в edu_options [edu_level]:' в ​​вашей третьей строке. В стороне, это может помочь инвертировать словарь для более быстрого поиска – inspectorG4dget

+0

, это то, что я изначально имел это, и он по-прежнему создавал ту же проблему. – pproctor

+0

'Эта проблема не возникала для входных strs, таких как 'bs biology' или 'bs business '.', потому что 'e' в' Completed College' находится в 'bs business', а' l' в 'Grad School' находится в' bs biology'. Я бы рекомендовал вам опубликовать ввод, а также ожидаемый результат для этого ввода, чтобы мы могли лучше понять вашу проблему. Также, пожалуйста, покажите нам, как вы вычисляете 'cleaned_string' – inspectorG4dget

ответ

1

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

В этом случае, это должно работать:

>>> edu_options = {'Completed College' : [ 'bachelor', 'ba', 'be', 'bs'], 'Grad Shool': ['phd', 'doctor']} 
>>> cleaned_string = 'phd' 
>>> for key, value in edu_options.items(): 
...  if cleaned_string in value:   # value is the list 
...   print key      # inside a function, use return 
... 
>>> Grad Shool 

Edit: Я думаю, что ошибка в вашем втором цикле, посмотрите, что происходит:

>>> edu_options = {'Completed College' : [ 'bachelor', 'ba', 'be', 'bs'], 'Grad Shool': ['phd', 'doctor']} 
>>> for edu_level in edu_options: 
...  for option in edu_level: # Right here 
...   print option 
... 
C 
o 
m 
p 
l 
e 
t 
e 
d 

C 
o 
l 
l 
e 
g 
e 
G 
r 
a 
d 

S 
h 
o 
o 
l 
>>> 

Оттуда 'л' выходит.

+0

пример желаемого вывода из edu_dict: input:« B-Arch »будет отредактирован by clean_edu(), чтобы стать «barch», который затем будет сравниваться со списками в edu_options и возвращает ключ, если список содержит str (например: «Completed College») – pproctor

+0

Итак, мой цикл должен работать, не так ли? Хотя я не понимал, есть ли/elif-операторы в конце вашего кода ... В любом случае значение «l» исходит из вашего второго цикла 'для параметра в edu_level:' таким образом, 'option' становится каждым символом ключей в dict. –

+0

ваш подход действительно дает несколько совпадений, но меньше моего текущего кода. Операторы if elif предоставляют возможность сломаться, как только правильное значение будет сопоставлено, а не итерации по всем частям списка. Так как набор данных будет очень большим, это важно – pproctor

Смежные вопросы