Python 3 - ValueError: not enough values to unpack (expected 3, got 2) Python 3 - 值错误:无法解包足够的值(期望3个,得到2个)

24
我在使用Mac OS X运行Python 3程序时遇到了问题,但这段代码本应该是可以正常运行的。
# -*- 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('abc@abc.com', '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('abc@abc.com', email, body)

if sendmailStatus != {}:
    print('There was a problem sending email to %s: %s' % (email,
    sendmailStatus))
smtpObj.quit()enter code here

当我尝试向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('abc@abc.com', email, body)

终端显示错误:

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)

2
这意味着函数unpaidMembers.items()不会以元组形式返回3个项目。尝试打印它的值以了解您得到的返回值类型:print unpaidMembers.items() - Carles Mitjans
1
你的代码与回溯信息不符。在代码中问题已经被纠正,但是缺少了一个冒号“:”。 - Klaus D.
看起来你正在尝试将包含两个项目的元组解包为三个不同的项目。就像@CarlesMitjans所说,尝试打印unpaidMembers.items()返回的值。您可能需要进行一些额外的处理才能将其转换为3个项目。 - The Stupid Engineer
5个回答

12

你可能想要分配你在这里读取的lastname

lastname = sheet.cell(row=r, column=3).value

转换为某物;当前程序只是忽略了它

你可以这样在两行之后实现

unpaidMembers[name] = lastname, email

你的程序仍然会在同一位置崩溃,因为.items()仍然不会给你3元组,而是一个具有这种结构的东西:(name, (lastname, email))

好消息是,Python可以处理这个问题。

for name, (lastname, email) in unpaidMembers.items():

9

1. 首先应理解错误的含义

not enough values to unpack (expected 3, got 2) 错误的含义是:

一个由两个元素组成的元组被赋值给 三个变量

我已经为您编写了演示代码:


#!/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()

使用 VSCode 调试效果:

notEnoughUnpack CrifanLi

2. 关于你的代码

for name, email, lastname in unpaidMembers.items():

但错误 ValueError: not enough values to unpack (expected 3, got 2)

意味着在unpaidMembers中的每个项目(元组值)只有1部分:email,这与上述代码相对应。

    unpaidMembers[name] = email

因此应将代码更改为:

for name, email in unpaidMembers.items():

为避免错误。
但显然您期望额外的lastname,因此应将上述代码更改为
    unpaidMembers[name] = (email, lastname)

更换为更好的语法:

for name, (email, lastname) in unpaidMembers.items():

那么一切都好了,清晰明了。


5
在这一行中:
for name, email, lastname in unpaidMembers.items():

unpaidMembers.items() 每次迭代必须只有两个值。

下面是一个小例子来说明这个问题:

以下代码可以正常工作:

for alpha, beta, delta in [("first", "second", "third")]:
    print("alpha:", alpha, "beta:", beta, "delta:", delta)

以下是你的代码,会导致失败:

for alpha, beta, delta in [("first", "second")]:
    print("alpha:", alpha, "beta:", beta, "delta:", delta)

在这个例子中,列表中没有足够的值被分配给 delta,所以它没有任何值。

1

由于 unpaidMembers 是一个字典,因此在使用 .items()调用时,它总是返回两个值 - (键,值)。您可能希望将数据保留为元组列表[(name, email, lastname), (name, email, lastname)..]


1

ValueErrors:在Python中,值是存储在某个对象内的信息。在Python中遇到ValueError意味着您尝试将值分配给的对象内容存在问题。

在您的情况下,有三个参数:名字、姓氏和电子邮件,但是unpaidmembers只包含其中的两个。

name, lastname, email in unpaidMembers.items() 所以您应该参考数据 或者您的代码可能是
lastname, email in unpaidMembers.items() 或者 name, email in unpaidMembers.items()


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接