Python 3 - ValueError:没有足够的值来解包(预期 3,得到 2)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42259166/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python 3 - ValueError: not enough values to unpack (expected 3, got 2)
提问by Jakub K?os
I have a problem with my Python 3 program. I use Mac OS X. This code is running properly.
我的 Python 3 程序有问题。我使用 Mac OS X。此代码运行正常。
# -*- coding: utf-8 -*-
#! python3
# sendDuesReminders.py - Sends emails based on payment status in spreadsheet.
import openpyxl, smtplib, sys
# Open the spreadsheet and get the latest dues status.
wb = openpyxl.load_workbook('duesRecords.xlsx')
sheet = wb.get_sheet_by_name('Sheet1')
lastCol = sheet.max_column
latestMonth = sheet.cell(row=1, column=lastCol).value
# Check each member's payment status.
unpaidMembers = {}
for r in range(2, sheet.max_row + 1):
payment = sheet.cell(row=r, column=lastCol).value
if payment != 'zaplacone':
name = sheet.cell(row=r, column=2).value
lastname = sheet.cell(row=r, column=3).value
email = sheet.cell(row=r, column=4).value
unpaidMembers[name] = email
# Log in to email account.
smtpObj = smtplib.SMTP_SSL('smtp.gmail.com', 465)
smtpObj.ehlo()
smtpObj.login('[email protected]', '1234')
# Send out reminder emails.
for name, email in unpaidMembers.items()
body = "Subject: %s - przypomnienie o platnosci raty za treningi GIT Parkour. " \
"\n\nPrzypominamy o uregulowaniu wplaty za uczestnictwo: %s w treningach GIT Parkour w ." \
"\n\nRecords show that you have not paid dues for %s. Please make " \
"this payment as soon as possible."%(latestMonth, name, latestMonth)
print('Sending email to %s...' % email)
sendmailStatus = smtpObj.sendmail('[email protected]', email, body)
if sendmailStatus != {}:
print('There was a problem sending email to %s: %s' % (email,
sendmailStatus))
smtpObj.quit()enter code here
Problems starts when I am trying to add next value to the for loop.
当我尝试将下一个值添加到 for 循环时,问题就开始了。
# Send out reminder emails.
for name, lastname, email in unpaidMembers.items()
body = "Subject: %s - przypomnienie o platnosci raty za treningi GIT Parkour. " \
"\n\nPrzypominamy o uregulowaniu wplaty za uczestnictwo: %s %s w treningach GIT Parkour w ." \
"\n\nRecords show that you have not paid dues for %s. Please make " \
"this payment as soon as possible."%(latestMonth, name, lastname, latestMonth)
print('Sending email to %s...' % email)
sendmailStatus = smtpObj.sendmail('[email protected]', email, body)
Terminal shows error:
终端显示错误:
Traceback (most recent call last):
File "sendDuesEmailReminder.py", line 44, in <module>
for name, email, lastname in unpaidMembers.items():
ValueError: not enough values to unpack (expected 3, got 2)
采纳答案by Paul Panzer
You probably want to assign the lastname
you are reading out here
您可能想在lastname
这里分配您正在阅读的内容
lastname = sheet.cell(row=r, column=3).value
to something; currently the program just forgets it
对某事;目前该程序只是忘记了它
you could do that two lines after, like so
你可以在两行之后做,就像这样
unpaidMembers[name] = lastname, email
your program will still crash at the same place, because .items()
still won't give you 3-tuples but rather something that has this structure: (name, (lastname, email))
你的程序仍然会在同一个地方崩溃,因为.items()
仍然不会给你 3 元组,而是具有这种结构的东西:(name, (lastname, email))
good news is, python can handle this
好消息是,python 可以处理这个
for name, (lastname, email) in unpaidMembers.items():
etc.
等等。
回答by xandermonkey
In this line:
在这一行:
for name, email, lastname in unpaidMembers.items():
unpaidMembers.items()
must have only two values per iteration.
unpaidMembers.items()
每次迭代必须只有两个值。
Here is a small example to illustrate the problem:
下面是一个小例子来说明这个问题:
This will work:
这将起作用:
for alpha, beta, delta in [("first", "second", "third")]:
print("alpha:", alpha, "beta:", beta, "delta:", delta)
This will fail, and is what your code does:
这将失败,这就是您的代码所做的:
for alpha, beta, delta in [("first", "second")]:
print("alpha:", alpha, "beta:", beta, "delta:", delta)
In this last example, what value in the list is assigned to delta
? Nothing, There aren't enough values, and that is the problem.
在最后一个示例中,列表中的哪个值被分配给delta
?没什么,没有足够的值,这就是问题所在。
回答by marcinowski
Since unpaidMembers
is a dictionaryit always returns two values when called with .items()
- (key, value). You may want to keep your data as a list of tuples [(name, email, lastname), (name, email, lastname)..]
.
由于unpaidMembers
是一个字典,它在使用.items()
- (key, value)调用时总是返回两个值。您可能希望将数据保存为元组列表[(name, email, lastname), (name, email, lastname)..]
。
回答by KARAN PATEL
ValueErrors :In Python, a value is the information that is stored within a certain object. To encounter a ValueError in Python means that is a problem with the content of the object you tried to assign the value to.
ValueErrors :在 Python 中,值是存储在某个对象中的信息。在 Python 中遇到 ValueError 意味着您尝试为其分配值的对象的内容存在问题。
in your case name,lastname and email 3 parameters are there but unpaidmembers only contain 2 of them.
在您的情况下,名称、姓氏和电子邮件有 3 个参数,但未付费会员仅包含其中的 2 个。
name, lastname, email in unpaidMembers.items()so you should refer data or your code might be
lastname, email in unpaidMembers.items()or name, email in unpaidMembers.items()
姓名、姓氏、电子邮件在 unpaidMembers.items() 中,因此您应该引用数据或您的代码可能是
姓氏、电子邮件在 unpaidMembers.items()或 姓名、电子邮件在 unpaidMembers.items()
回答by crifan
1. First should understand the error meaning
1.首先要了解错误的含义
Error not enough values to unpack (expected 3, got 2)
means:
错误not enough values to unpack (expected 3, got 2)
意味着:
a 2 parttuple, but assign to 3 values
一个2 部分元组,但分配给3 个值
and I have written demo code to show for you:
我已经编写了演示代码为您展示:
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Function: Showing how to understand ValueError 'not enough values to unpack (expected 3, got 2)'
# Author: Crifan Li
# Update: 20191212
def notEnoughUnpack():
"""Showing how to understand python error `not enough values to unpack (expected 3, got 2)`"""
# a dict, which single key's value is two part tuple
valueIsTwoPartTupleDict = {
"name1": ("lastname1", "email1"),
"name2": ("lastname2", "email2"),
}
# Test case 1: got value from key
gotLastname, gotEmail = valueIsTwoPartTupleDict["name1"] # OK
print("gotLastname=%s, gotEmail=%s" % (gotLastname, gotEmail))
# gotLastname, gotEmail, gotOtherSomeValue = valueIsTwoPartTupleDict["name1"] # -> ValueError not enough values to unpack (expected 3, got 2)
# Test case 2: got from dict.items()
for eachKey, eachValues in valueIsTwoPartTupleDict.items():
print("eachKey=%s, eachValues=%s" % (eachKey, eachValues))
# same as following:
# Background knowledge: each of dict.items() return (key, values)
# here above eachValues is a tuple of two parts
for eachKey, (eachValuePart1, eachValuePart2) in valueIsTwoPartTupleDict.items():
print("eachKey=%s, eachValuePart1=%s, eachValuePart2=%s" % (eachKey, eachValuePart1, eachValuePart2))
# but following:
for eachKey, (eachValuePart1, eachValuePart2, eachValuePart3) in valueIsTwoPartTupleDict.items(): # will -> ValueError not enough values to unpack (expected 3, got 2)
pass
if __name__ == "__main__":
notEnoughUnpack()
using VSCode
debug effect:
使用VSCode
调试效果:
2. For your code
2. 对于您的代码
for name, email, lastname in unpaidMembers.items():
but error
ValueError: not enough values to unpack (expected 3, got 2)
但错误
ValueError: not enough values to unpack (expected 3, got 2)
means each item(a tuple value) in unpaidMembers
, only have 1 parts:email
, which corresponding above code
表示 中的每一项(一个元组值)unpaidMembers
,只有 1 个部分:email
,对应上面的代码
unpaidMembers[name] = email
so should change code to:
所以应该将代码更改为:
for name, email in unpaidMembers.items():
to avoid error.
以免出错。
But obviously you expect extra lastname
, so should change your above code to
但显然你期望额外的lastname
,所以应该将上面的代码更改为
unpaidMembers[name] = (email, lastname)
and better change to better syntax:
并更好地更改为更好的语法:
for name, (email, lastname) in unpaidMembers.items():
then everything is OK and clear.
然后一切正常。