简体   繁体   中英

Converting text file to list and getting at it using indexes:

Can anyone tell me why this doesn't work (Python 3) and what I need to do to fix it. Code and error message below:

def verifylogin():

fin=open("moosebook.txt","r")
data=fin.readlines()
line=data

allData = []
for ln in line.split(')('):
    allData.append( ln.lstrip('(').rstrip(')').replace("'", '').replace(' ', '').split(',') )

for data in allData:
    print (data[0]) # print user
print (data[5]) # print profession

output error message:

line 30, in verifylogin
for ln in line.split(')('):

AttributeError: 'list' object has no attribute 'split'

The data in the text file is:

('CoderBlogJ', 'ggs123', 'J', 'Bloggs', 'Male', 'Coder')('DoctorSmitD', 'ith123', 'D', 'Smith', 'Male', 'Doctor')('teacherminaR', 'neb123', 'R', 'minajneb', 'female', 'teacher')('WriterGardK', 'ens123', 'K', 'Gardens', 'Male', 'Writer')('', '123', '', '', '', '')('', '123', '', '', '', '')('', '123', '', '', '', '')

I want data[0] and data[5] etc to print out the relevant field in the list.

Thank you very much for the answer: My final quest however, is to get the username and password to work and because I can't translate it, I can't quite get it to work ....

def verifylogin():
    with open("moosebook.txt") as f:
        data = literal_eval(f.read().replace(")", "),"))
    for user, pw,_,sur,_, job in data: 
        if user:
               print("{}  is a {}".format(user, pw))

     flag=0
for counter in range(0,len(data)):
    if textlogin.get()==data[counter] and textpassword.get()==data[counter+1]:
        flag=flag+1

if flag>0:
            welcome=Label(myGui,text="Access Granted. Loading Profile ....")
            welcome.pack()
else:
                denied=Label(myGui,text="Access Denied")
                denied.pack() 

Your error as stated already is because line is a reference to data which is a list, if each tuple is on a separate line in your file you can use ast.literal_eval to parse the data and just index the tuples to get the dat you want:

from ast import literal_eval
def verifylogin():

    with open("test.csv") as f:
        for line in f:
            print(literal_eval(line))
verifylogin()

Output:

('CoderBlogJ', 'ggs123', 'J', 'Bloggs', 'Male', 'Coder')
('DoctorSmitD', 'ith123', 'D', 'Smith', 'Male', 'Doctor')
('teacherminaR', 'neb123', 'R', 'minajneb', 'female', 'teacher')
('WriterGardK', 'ens123', 'K', 'Gardens', 'Male', 'Writer')
('', '123', '', '', '', '')
('', '123', '', '', '', '')
('', '123', '', '', '', '')

If you have it all in a single line you can str.replace putting a trailing comma after each ) , that will wrap all the tuples in a tuple so ast can parse the file content correctly:

def verifylogin():
    with open("test.csv") as f:
        data = literal_eval(f.read().replace(")", "),"))
        for t in data:
            print(t)


verifylogin()

Output will be the same as previously.

If you are using python3 we can use extended iterable unpacking to get the data we want, ignoring the data with no user with an if check:

from ast import literal_eval

def verifylogin():
    with open("test.csv") as f:
        data = literal_eval(f.read().replace(")", "),"))
        for user, *rest, job in data: # python2 ->  for user, _,_,_,_, job in data:
            if user:
                   print("{}  is a {}".format(user, job))

Output:

CoderBlogJ  is a Coder
DoctorSmitD  is a Doctor
teacherminaR  is a teacher
WriterGardK  is a Writer

You can get whatever info you want, all the data is unpacked in the loop:

def verifylogin():
    with open("test.csv") as f:
        data = literal_eval(f.read().replace(")", "),"))
        for user, pw, _, _ , _, job in data:
            if user:
                print("Details for user: {}\nPassword: {}\nJob: {}\n".format(user, pw, job))

Output:

Details for user: DoctorSmitD
Password: ith123
Job: Doctor

Details for user: teacherminaR
Password: neb123
Job: teacher

Details for user: WriterGardK
Password: ens123
Job: Writer

file.readlines() returns a list of lines in.

you did:-

data = fin.readlines()

then data is a list not string

line = data

line is a list too, and list don't have split method.

Try type() function.

 type(data.readlines())
 list

With the format of the data you give (one line with multiple tuples), and keeping your code, try the following.

def verifylogin():
    fin = open("moosebook.txt", "r")
    data = fin.readlines()

    allData = []
    for line in data:
            for ln in line.split(')('):
                allData.append(ln.lstrip('(').rstrip(')').replace("'", '').replace(' ', '').split(','))

    for data in allData:
        print(data[0])  # print user
        print(data[5])  # print profession

verifylogin()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM