我编写了一个Python程序,使用tkinter和pandas来选择行并通过电子邮件发送。
程序让用户决定要操作哪个excel文件;
- 然后询问要操作该文件的哪一页;
- 然后它询问你想要选择多少行(使用。tail函数);
- 则程序应该遍历行并从单元格(在所选行中)读取电子邮件地址;
- 然后将正确的行发送到正确的地址。
我被困在迭代过程中。
代码如下:
import pandas as pd
import smtplib
def invio_mail(my_tailed__df): #the function imports the sliced (.tail) dataframe
gmail_user = '###'
gmail_password = '###'
sent_from = gmail_user
server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
server.ehlo()
server.login(gmail_user, gmail_password)
list = my_tailed_df
customers = list['CUSTOMER']
wrs = list['WR']
phones = list['PHONE']
streets = list['STREET']
cities = list["CITY"]
mobiles = list['MOBILE']
mobiles2 = list['MOBILE2']
mails = list['INST']
for i in range(len(mails)):
customer = customers[i]
wr = wrs[i]
phone = phones[i]
street = streets[i]
city = cities[i]
mobile = mobiles[i]
mobile2 = mobiles2[i]
"""
for i in range(len(mails)):
if mails[i] == "T138":
mail = "email_1@gmail.com"
elif mails[i] == "T139":
mail = "email_2@gmail.com"
"""
subject = 'My subject'
body = f"There you go" n Name: {customer} n WR: {wr} n Phone: {phone} n Street: {street} n City: {city} n Mobile: {mobile} n Mobile2: {mobile2}"
email_text = """
From: %s
To: %s
Subject: %s
%s
""" % (sent_from, ", ".join(mail), subject, body)
try:
server.sendmail(sent_from, [mail], email_text)
server.close()
print('Your email was sent!')
except:
print("Some error")
程序抛出KeyError: 0进入for循环后,在循环内的第一行:customer = customers[i]
我知道注释部分(嵌套的for循环)也会抛出同样的错误。
我的头撞在墙上,我想我已经读过并尝试了所有的方法。
我的错误在哪里?
事情开始出错了:list = my_tailed_df
。在Python中,list()是内置类型。
但是,使用list = my_tailed_df
,您将覆盖该类型。你可以检查这个:
# before the line:
print(type(list))
<class 'type'>
list = my_tailed_df
# after the line:
print(type(list))
<class 'pandas.core.frame.DataFrame'> # assuming that your df is an actual df!
这是一种不好的做法,不会以混淆为代价增加功能上的好处。例如,customers = list['CUSTOMER']
正在做与customers = my_tailed_df['CUSTOMER']
完全相同的事情,即创建一个pd。使用my_tailed_df中的索引进行序列。因此,首先要做的是去掉list = my_tailed_df
,并将所有list[...]
代码段更改为my_tailed_df[...]
。
接下来,让我们看看你的错误。for i in range(len(mails)):
生成i = 0, 1, ..., len(mails)-1
。因此,您要做的是访问pd。索引0, 1
等的系列。如果你得到错误KeyError: 0
,这必须意味着原来的df指数指数中不包含这个键(例如id的列表之类的)。
如果您不需要原始索引(似乎就是这种情况),您可以通过重置索引来纠正这种情况:
my_tailed_df.reset_index(drop=True, inplace=True)
print(my_tailed_df.index)
# will get you: RangeIndex(start=0, stop=x, step=1)
# where x = len(my_tailed_df)-1 (== len(mails)-1)
在行customers = my_tailed_df['CUSTOMER']
之前实现重置(所以,而不是list = my_tailed_df
),你应该很好。
或者,您可以保留原始索引,并将for i in range(len(mails)):
更改为for i in mails.index:
。
最后,如果您想同时跟踪索引元素的位置(idx)和它的值(element),您还可以使用for idx, element in enumerate(mails.index):
。