1

I have the following code

def retrieve_user(username):

    with open(users_file, 'r', encoding='utf-8') as f:

        items = []
        line_num = 0
        for line in f:
            line_num = line_num+1
            #print(items)
            if line_num > 1:
                items = line.split(';')
                name = items[0]
                area = items[1]
                all_keywords = items[2].split('$')

                if name in user.keys():
                    user[name].append([area, all_keywords])
                else:
                    user[name] = [area, all_keywords]

        if username in user.keys():
            print(user[username])
        else:
            print('User ', username, ' could not be found')
            login_user()

    return False

and now i get the following error. does anybody knows why? I have stuck and i don't know what I am doing wrong.

**area = items[1]
IndexError: list index out of range**

the file that i am trying to retrieve the data looks like this

user;area;keywords

mike;Sports: Football;Arsenal

john;Technology: IBM;CPU

thank you in advance

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
newbie
  • 13
  • 4

1 Answers1

1

You have empty lines in the file, if you split a empty line on ; you do not have an index of 1 in the resulting item. Error tells you as much.

Your code is missing crucial codeparts (f.e. the user dict):

Try this:

with open(users_file, 'r', encoding='utf-8') as f:
   txt = f.read()

# txt = """user;area;keywords
#
# mike;Sports: Football;Arsenal
# 
# john;Technology: IBM;CPU"""

# split each line on newlines, take only lines thats have non-whitespace in it. 
# split those line at ;
splitted = [x.split(";") for x in txt.splitlines() if x.strip() != ""]
print(splitted)

Output:

[['user', 'area', 'keywords'], 
 ['mike', 'Sports: Football', 'Arsenal'], 
 ['john', 'Technology: IBM', 'CPU']]

Accessing the parsed lists by row:

for name, area, words in splitted[1:]:  # skips the first row via list comprehension, 
                                        # and decompose each inner list into name,
                                        # area and words
    all_keywords = words.split("$")
    print(name, "    ", area , "    ", all_keywords)

Output:

mike      Sports: Football      ['Arsenal']
john      Technology: IBM      ['CPU']

If you want to create keys into dictionarys, you can leverage dict.setdefault(key,defaultvalue):

if name in user.keys():
    user[name].append([area, all_keywords])
else:
    user[name] = [area, all_keywords]

is roughly equivalent to:

user.setdefault(name,[]).extend([area, all_keywords])  

This creates the key with an empty list if it does not yet exists. The value is returned by setdefault and extend(...) adds to it your current data. If the key exists, setdefault simpley returns the value and also extends it. Win-Win: your list grows.

See https://docs.python.org/3/library/stdtypes.html#dict or this answer: https://stackoverflow.com/a/3483652/7505395

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
  • @newbie The code reads the complete file into `txt` (if you uncomment `with open(users_file, 'r', encoding='utf-8') as f:` and the next line). `splittet` is a list, each non-empty line in your file is one list-entry and each entry is split at `;` the `for name,area, words in splitted[1:]:` skips the "headerrow" and gives you each lines `name`, `area` and `words`. Thats about what you do above, you can use those 3 on your user-dict and do what you need to do – Patrick Artner Jan 15 '18 at 21:22