Skip to content
Advertisement

Python List to Dictionary from a file

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')
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement