Help with code! "Too many values to unpack" (original) (raw)
Code:
def view():
with open("passwords.txt", 'r') as f:
for line in f.readlines():
data = line.rstrip()
user, passw = data.split("|")
print("User:", user, "| Password:", passw)
Error message:
`File "c:\Users\Josh Lee\Python\Hello World\password_manager.py", line 27, in <module>
view()
File "c:\Users\Josh Lee\Python\Hello World\password_manager.py", line 8, in view
user, passw = data.split("|")
ValueError: too many values to unpack (expected 2)
This is my code. I have tried to change line 8, but it’ll say too little expected (expected: 2 got:1) and then it’ll show this. I’ve been stuck on this for a while and would like some pointers on where I can improve the code
MRAB (Matthew Barnett) April 26, 2025, 2:24am 2
Please don’t post screenshots.
Copy and paste any code or traceback, and in order to preserve formatting, select the code or traceback that you posted and then click the </>
button.
What is the value of data
? What is the value of data.split("|")
? Print them out to check what they actually are.
Also, I find it strange that the code says data.split("|")
but the traceback appears to say data.split("| ")
. Note the extra space in the string.
TheJoshDude (The Josh Dude) April 26, 2025, 3:14am 3
ok i got rid of the screenshot, thanks! ok ill play around with it and see if anything changes but so far it still hasn’t worked
hprodh (hprodh) April 26, 2025, 5:05am 4
It seems the problem is that some line do not have a “|” character, thus data.split("|")
does not return two parts but one.
jeff5 (Jeff Allen) April 27, 2025, 10:08am 5
Ah, but it is “too many values to unpack” not “too few”. So some lines have more than one "|"
.
@TheJoshDude : these things are easily diagnosed if you print out what you’re getting, as @MRAB suggests. If necessary, do the troublesome part in smaller steps. If it’s a long file, you might need like to save yourself some reading e.g.:
temp = data.split("|")
if len(temp) != 2:
print(f"{temp=} {data=}")
user, passw = temp
Or the same kind of logic in the debugger.
CAM-Gerlach (C.A.M. Gerlach) April 27, 2025, 10:44am 6
Or, kill two birds with one stone by incorporating some basic error handling in your code—this will print errors that occur and the lines on which they do (so you can check them in your file). Once you decide how you want to handle lines with more or fewer separators than you expect, you can add the appropriate code to the except
block.
for idx, line in enumerate(f.readlines()):
data = line.rstrip()
try:
user, pass = data.split("|")
except ValueError as e:
print("Could not parse line {idx + 1}: {e}"
continue
print("User:", user, "| Password:", pass)
Also, there’s no benefit to using readlines()
over just iterating over the file object directly; it is way less memory-efficient while requiring extra code. Additionally, unless you know the file will be in a dynamic OS locale encoding rather than a fixed one (presumably UTF-8), you’ll want to add the encoding
arg to open()
so you can handle passwords with special characters on systems that don’t happen to have the OS locale default to UTF-8 (or whatever you’re expecting). Thus:
def view():
with open("passwords.txt", 'r', encoding="UTF-8") as f:
for idx, line in enumerate(f):
data = line.rstrip()
try:
user, pass = data.split("|")
except ValueError as e:
print("Could not print line {idx + 1}: {e}"
else
print("User:", user, "| Password:", pass)
hprodh (hprodh) April 27, 2025, 11:09am 7
Ah, yes, probably some passwords have a “|” inside.
c-rob (Chuck R.) April 29, 2025, 3:10pm 8
I think data.split() needs to return a list like this:
[user, passw] = data.split("|")
jeff5 (Jeff Allen) April 29, 2025, 3:43pm 9
split
does return a list but it isn’t necessary to reflect that in the LHS. Try it.
Also, @hprodh, if one is confident it is the password and not the user name that has the '|'
, one could use the maxsplit
argument.
a = "a|b|c"
a.split('|', 1) # = 'a', 'b|c'