筛选有效邮箱时调用filter函数出现TypeError: 'bool' object is not callable错误
解决TypeError: 'bool' object is not callable的邮箱筛选问题
兄弟,咱先说说你为啥会碰到这个报错:你把fun(email)的结果(一个布尔值)传给了filter函数,但filter的第一个参数要求是可以被调用的函数,不是一个布尔值!你看,a=fun(email)这行代码里,fun接收的是整个邮箱列表,返回的是True或者False,然后你把这个布尔值塞给filter,它当然会抱怨“布尔值不能被调用”啦。
另外你的fun函数逻辑也有几个小问题,咱一起捋捋:
('@'and'.') in i这个写法完全不对,这等价于'.' in i,因为@是真值,所以@ and .的结果是.,根本没检查@是否存在fun现在接收的是整个邮箱列表,但我们需要它处理单个邮箱字符串,这样filter才能逐个把列表里的邮箱传进去校验- 原函数里如果邮箱没有
@和.,居然返回True,这明显不符合有效邮箱的要求 - 用
url.split(".")拆分的话,如果url里有多个点(比如example.co.uk),会直接报错,因为你试图把一个长度大于2的列表解包成两个变量
咱直接上修正后的代码,一步一步改到位:
首先是校验单个邮箱的函数:
def fun(email): # 先做基础校验:必须有且只有一个@,同时包含.,且@不能在首尾 if '@' not in email or email.count('@') != 1 or '.' not in email: return False user_part, url_part = email.split('@') # 校验url部分:必须包含.,且.不能在开头或结尾 if '.' not in url_part or url_part.startswith('.') or url_part.endswith('.'): return False # 拆分域名部分:用rsplit从右边拆一次,兼容url里有多个子域名的情况 web_part, domain_part = url_part.rsplit('.', 1) # 校验用户名:只能包含字母数字、-、_ if not user_part.replace('-', '').replace('_', '').isalnum(): return False # 校验web部分:只能是字母数字 if not web_part.isalnum(): return False # 校验域名长度不超过3 if len(domain_part) > 3: return False # 所有校验通过,返回True return True
然后是主函数部分,直接把fun传给filter就行,不用提前调用:
if __name__ == "__main__": n = int(input()) email_list = [raw_input().strip() for _ in range(n)] valid_emails = list(filter(fun, email_list)) valid_emails.sort() print(valid_emails)
咱再说说关键的修改点:
- 去掉了
a=fun(email)这行,直接用filter(fun, email_list),因为filter会自动遍历email_list,把每个元素传给fun做校验 - 修正了
@和.的判断逻辑,确保邮箱格式的基础合法性 - 用
rsplit('.', 1)代替split('.'),避免多个点导致的解包错误 - 修正了原函数中错误的返回逻辑,现在不符合条件的邮箱都会返回False
- 给变量改了更清晰的名字(比如
email_list代替email),代码可读性更好
内容的提问来源于stack exchange,提问作者Ravi Ranjan
相关产品推荐
相关产品推荐

