-5

i'm a bit new and i'm working on a login mechanism. All the usernames and passwords are stored in a list like [[username,passwort],[username,password]], which is then written in a textfile in the format: Username Password

                                      for example:   Julia
                                                     x1234
                                                     Nick
                                                     doggoXX123
                                      and so on

when the programm starts I want to put them back in a list of usernames and passwords. To do that I wrote a function called read_from_file(), which takes two lines from the text file (the username and underthat the password) in a list (called user_data) and than adds the list to the main list of users (called user_list) [username, password] -> (mainlist:) [[username],[password]] Here is the code:

def read_from_file():
    
    user_list = []

    f = open("userdata.txt", "r")

    user_data = ["", ""]
    line_counter = 0

    for x in f:

        user_data[line_counter] = x
        line_counter += 1
        print(line_counter)

        if line_counter == 2:
            print(user_list)
            line_counter = 0
            user_list.append(user_data)

Now heres my problem: When I append the user_data to the user_list, the second time I append it also the first list appended to the user_list changes for example:

user_list = [[Julia, x1234]]

-> second time for loop goes through

user_list = [[Nick, doggoXX123],[Nick, doggoXX123]]

and it should ACTUALLY be

user_list = [[Julia, x1234],[Nick, doggoXX123]]

eventough the first item in the list should be [Julia, x1234]

SO how to I stop it from changing?

Now it tested this with a var called i and put it into a list and then changed the var again and put it a second time in the list and it worked how I thought it should:

def test():

    list = []

    i = 1

    list.append(i)

    i += 1

    list.append(i)

    print(list)
    print(i)

output was [1,2] ; 2

just as expected

Now why doesnt this work with the list? Why does the list change and the var not?

MOFRA
  • 3
  • 1
  • The problem looks like the one here: https://stackoverflow.com/questions/240178/list-of-lists-changes-reflected-across-sublists-unexpectedly. Please see if this answers your question on the behaviour – jrmylow Sep 19 '20 at 11:18

2 Answers2

0

The problem you're experiencing is due to a misunderstanding of lists, list-references, and possibly the concept of mutability.

In your case, you are binding the name user_data to a list object. In other words, user_data acts as a list-reference to the actual list object in memory.

When you say user_list.append(user_data), all you're doing is appending a list-reference to user_list. It doesn't make a deep copy, or anything like that. So, if you have two username-password-pairs, then you'll have two list-references, both pointing to the same underlying list in memory. Any change you make to the list object through any of its references will be reflected in all other references, since they're all just "pointing" to the same place.

>>> empty_list = []
>>> lists = [empty_list, empty_list]
>>> lists[0]
[]
>>> lists[1]
[]
>>> lists[0].append(1)
>>> lists[0]
[1]
>>> lists[1]
[1]
>>> 
Paul M.
  • 10,481
  • 2
  • 9
  • 15
0

You declared user_data outside the for loop. So, there's a single user_data which you're modifying in each iteration and you are appending another reference to the same list every time.

It would be much cleaner if your store the names, passwords in a lines each. Something like this:

name1 pass1
name2 pass2

Then you can retrieve like this

def read_from_file():
    user_list = []
    f = open("userdata.txt", "r")
    for line in f:
       user_list.append(line.split())
    print(user_list)
Mohammed
  • 313
  • 2
  • 9