I have a file of notes that im trying to convert to a dictionary. I got the script working but failed to output the data im looking for when there are repeated values.
In short took the file commands or comments which are separated by # as per below. I take that list and seperate the 1st column “key” by # and the rest is the comment or definition. Then i check the magic word im looking for, parse it match it and then to out.
Flashcards file as per below
> car # automobile 4 wheels and run > washington dc # the capital of United States > fedora # an operating distro > cat file # reads the file > car nissan # altima > car nissan # altima ## first car > car nissan # maxima > car nissan # rougue flashcard_dict = dict() flashcard_file = open('FlashCards','r') enter = input("Searching nemo: ") firstcolumn_str_list = list() for x in flashcard_file: flashcard_sprint = x.strip() flascard_clean = flashcard_sprint.split("#",1) firstcolumn_str = flascard_clean[0] firstcolumn = firstcolumn_str.strip() firstcolumn_str_list.append(firstcolumn) secondcolumn = flascard_clean[1] flashcard_dict[firstcolumn] = secondcolumn print print ("###" * 3) lista = list() # this is version 4 - where lambda works but fails as it matches the string in all words. # so if the word is "es" all patterns are matched that has "es" AND NOT the specific word filter_object = filter(lambda a: enter in a, firstcolumn_str_list) for x in filter_object: lista.append(x) print (lista) cc = 0 if cc < len(lista): for lambdatodictmatch in lista: if lambdatodictmatch in flashcard_dict: print (flashcard_dict[lambdatodictmatch]) else: print ("NONEsense... nothing here") else: print ("NONEsense... nothing here")
Again it works but when i search for car nissan. I get four responses but i only get the last “rougue” output or i get 4 repeated response “rougue”.
what’s the best way to accomplish this?
Advertisement
Answer
If you may have repeated elements then you should always use lists to keep even single value
if firstcolumn not in flashcard_dict: flashcard_dict[firstcolumn] = [] firstcolumn[firstcolumn].append(secondcolumn)
instead of
flashcard_dict[firstcolumn] = secondcolumn
EDIT:
Full working code with other changes
- first I used shorter and more readable names for variables,
- I read file at start and later use loop to ask for different cards.
- I added command
!keys
to display all keys, and!exit
to exit loop and finish program, list(sorted(flashcards.keys()))
gives all keys from dictionary without repeating values (and sorted)
I used io
only to simulate file in memory – so everyone can simply copy and run this code (without creating file FlashCards
) but you should use open(...)
text = '''car # automobile 4 wheels and run washington dc # the capital of United States fedora # an operating distro cat file # reads the file car nissan # altima car nissan # altima ## first car car nissan # maxima car nissan # rougue ''' import io # --- constansts --- DEBUG = True # --- functions --- def read_data(filename='FlashCards'): if DEBUG: print('[DEBUG] reading file') flashcards = dict() # with `s` at the end because it keeps many flashcards #file_handler = open(filename) file_handler = io.StringIO(text) for line in file_handler: line = line.strip() parts = line.split("#", 1) key = parts[0].strip() value = parts[1].strip() if key not in flashcards: flashcards[key] = [] flashcards[key].append(value) all_keys = list(sorted(flashcards.keys())) return flashcards, all_keys # --- main --- # - before loop - # because words `key` and `keys` are very similar and it is easy to make mistake in code - so I added prefix `all_` flashcards, all_keys = read_data() print("#########") # - loop - while True: print() # empty line to make output more readable enter = input("Searching nemo (or command: !keys, !exit): ").strip().lower() print() # empty line to make output more readable if enter == '!exit': break elif enter == '!keys': #print( "n".join(all_keys) ) for key in all_keys: print('key>', key) elif enter.startswith('!'): print('unknown command:', enter) else: # keys which have `enter` only at #selected_keys = list(filter(lambda text: text.startswith(enter), all_keys)) # keys which have `enter` in any place (at the beginning, in the middle, at the end) selected_keys = list(filter(lambda text: enter in text, all_keys)) print('selected_keys:', selected_keys) if selected_keys: # instead of `0 < len(selected_keys)` for key in selected_keys: # `selected_keys` has to exist in `flashcards` so there is no need to check if `key` exists in `flashcards` print(key, '=>', flashcards[key]) else: print("NONEsense... nothing here") # - after loop - print('bye')