Есть ли способ найти слово из csv-файла только с первыми несколькими буквами?

#python #csv #telegram-bot

Вопрос:

Я новичок в программировании. Я создал англо-малаяламский словарь-бот для telegram на python. Это работает нормально. Но я подумываю об обновлении. База данных представляет собой CSV-файл (разделенный вкладками). Бот ищет введенное слово и отвечает пользователю результатами (определениями малаялама). проверьте скриншот здесь.

Он ищет все слово целиком. Но я хочу, чтобы бот выдал мне результаты только с двумя или тремя буквами в качестве входных данных. Например, когда я набираю «ent», мне нужны результаты всех слов, начинающихся с «ent». Скриншот здесь.

Мой текущий код приведен ниже. (раздел поиска)

 import csv

def malayalamDict(word):
    mDict = []
    mDef = []
    eWrd = []
    with open("data/olam-enml.csv", "r") as f:
        r = csv.reader(f)
        for i in r:
            if word in i[0]:
                mDict.append(i[0].split('t'))
        for j in range(0, len(mDict)):
            mDef.append(str(mDict[j][-1]))
        for k in range(0, len(mDict)):
            eWrd.append(str(mDict[k][1]))
    return mDef, eWrd
 

Мой пример файла CSV:

 id english_word part_of_speech definition
14007   Entity  n   സത്ത
14008   Entity  n   അസ്‌തിത്വം
14009   Entity  n   വസ്‌തു
138185  Entity  n   നിലനില്‌പ്‌
138186  Entity  n   ഉണ്മ
207395  Entity  n   നിലനില്പ്
 

Пожалуйста, кто-нибудь, помогите мне здесь.

Комментарии:

1. Это то, что вы ищете? if i[0].startswith(word):

2. Да, я думаю, что это так. Я попробую это сделать. Спасибо.

3. @Barмар: Пожалуйста, опубликуйте это как ответ, чтобы ОП мог принять его (если он работает), и чтобы другие пользователи могли проголосовать за него и дать вам репутацию! ;-).

4. Если word это первые несколько букв, word in i[0]: то тоже будет верно. Я не уверен, зачем вам нужен этот более конкретный тест.

5. @Бармар, это не сработало. если я[0].начинается с(слова): неверно. ///Если слово состоит из первых нескольких букв, слово в i[0]: также будет истинным. Я не уверен, зачем вам нужен этот более конкретный тест./// — Я пытаюсь добавить функцию предложения слов в бота.

Ответ №1:

для проверки первых букв вы можете использовать text.startswith(word) , но у вас есть несколько других проблем, из-за которых это может не сработать.

Вы сравниваете ent с Entity , и вы должны использовать lower() (или upper() ) для сравнения entity .

Вы проверяете word i[0] это раньше split() , чтобы сравнить с 14007 Entity n സത്ത этим . Вы должны просто использовать csv_reader(..., delimiter='t') его для автоматического разделения, а затем вы можете сравнить его со вторым столбцом row[1]

Этот код работает с вашим файлом csv , который вы добавили в своем комментарии здесь — он дает 307 результатов для ent

 import csv

def malayalam_dict(word):
    malayalam_definition = []
    english_word = []
    
    word = word.lower()

    with open("olam-enml.csv", "r") as f:
        cvs_reader = csv.reader(f, delimiter='t')

        #for (id_, english, part_of_speech, definition) in cvs_reader:
        for row in cvs_reader:
            #(id_, english, part_of_speech, definition) = row
            if row[1].lower().startswith(word):
                malayalam_definition.append(row[-1])
                english_word.append(row[1])
                
    return malayalam_definition, english_word

definitions, words = malayalam_dict('ent')

print(len(definitions))
 

Чтобы сделать код более читабельным, я использую полные имена переменных.

Смотрите больше: PEP 8 — Руководство по стилю для PythonCde


Редактировать:

Я бы сохранил результаты в виде пар (definition, english) , а не отдельных списков.

Я бы также использовал регулярное выражение для более сложного поиска

 import csv
import re

def malayalam_dict(word, regex=False):
    results = []
    
    word = word.lower()
    
    with open("olam-enml.csv", "r") as f:
        cvs_reader = csv.reader(f, delimiter='t')
        #for (id_, english, part_of_speech, definition) in cvs_reader:
        for row in cvs_reader:
            #(id_, english, part_of_speech, definition) = row
            if regex:
                if re.findall(word, row[1].lower()):
                    results.append( (row[-1], row[1]) )
            else:
                if row[1].lower().startswith(word):
                    results.append( (row[-1], row[1]) )
                
    return results

results = malayalam_dict('ent')               # normal `startswith()`
results = malayalam_dict('^ent', regex=True)  # regex

print(len(results))

for number, (definition, english) in enumerate(results, 1):
    print(f'{number:4} | {english:20}: {definition}')
 

Результат:

 307
   1 | Entail              : പ്രത്യേകപിന്‍തുടര്‍ച്ചക്രമം
   2 | Entail              : ദാനവിക്രയാദി അധികാരങ്ങളില്ലാതെ തലമുറയായി അനുഭവിക്കുന്നതിനു നല്‍കിയ സ്വത്ത്‌
   3 | Entail              : അന്യാധീനപ്പെടുത്താന്‍ പാടില്ലാത്ത വിധം നല്‍കുക
   4 | Entail              : ചുമത്തുക
   5 | Entail              : അനിവാര്യമാക്കിത്തീര്‍ക്കുക
   6 | Entail              : കൈമാറ്റം ചെയ്യാന്‍ അധികാരമില്ലാത്ത വസ്‌തുവകകളുടെ പിന്‍തുടര്‍ച്ചാവകാശം
   7 | Entail              : ആവശ്യമായി വരുക
   8 | Entail              : അന്യാധീനപ്പെടുത്താന്‍ പാടില്ലാത്ത വിധം അവകാശം കൊടുക്കുക
   9 | Entail              : കൈമാറ്റം ചെയ്യാന്‍ അധികാരമില്ലാത്ത വസ്തുവകകളുടെ പിന്‍തുടര്‍ച്ചാവകാശം
  10 | Entailer            : അവകാശമായി വിട്ടുകൊടുക്കുന്നവന്‍
  11 | Entangle            : കുടുക്കുക
  12 | Entangle            : അകപ്പെടുത്തുക
  13 | Entangle            : സങ്കീര്‍ണ്ണീകരിക്കുക
  14 | Entangle            : കെട്ടുപിണയുക
  15 | Entangle            : വിഷമിക്കുക
  16 | Entangle oneself with: മറ്റുള്ളവരുമായി വഴക്കടിച്ച്‌ പ്രശ്‌നമുണ്ടാക്കുക

  ...
 

Комментарии:

1. Это моя ссылка на результат