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?
CodePudding user response:
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')