Python匹配email.txt与users.txt对应ID的代码问题求助
问题描述
我有两个文件:email.txt和users.txt,内容示例如下:
email.txt
test3@gmail.com test@gmail.com test2@gmail.com
users.txt
test@gmail.com:1030072275212435458 test2@gmail.com:731498530124070912 test3@gmail.com:846414846449654846
需求
遍历email.txt中的每个邮箱,输出users.txt中对应邮箱的ID,预期输出:
846414846449654846 1030072275212435458 731498530124070912
我的代码
users = open("users.txt", 'r') with open("email.txt", 'r') as f: for email in f: for i in users.readlines(): if i.startswith(email[:-1]): ID = i.split(':')[1][:-1] print(ID)
遇到的问题
代码仅输出email.txt中第一个邮箱对应的ID,其余邮箱的ID都被忽略了,求解决办法。
问题原因与解决方法
原因分析
文件对象的readlines()方法只能读取一次:读完后文件指针会停在文件末尾,后续再调用readlines()只会返回空列表。第一次循环处理第一个邮箱时,已经把users.txt的内容全部读完了,后面的邮箱循环时,users.readlines()没有内容,自然找不到对应ID。
修复方案
方案1:提前加载为字典(高效推荐)
把users.txt的内容转成「邮箱-ID」的字典,遍历email.txt时直接通过字典查找,时间复杂度更低,也避免了重复读文件的问题:
# 先将users.txt内容加载到字典 user_map = {} with open("users.txt", 'r') as u_f: for line in u_f: email, user_id = line.strip().split(':') user_map[email] = user_id # 遍历email.txt输出对应ID with open("email.txt", 'r') as e_f: for email in e_f: cleaned_email = email.strip() if cleaned_email in user_map: print(user_map[cleaned_email])
方案2:每次循环重置文件指针
如果不想用字典,也可以在处理每个邮箱前,将users文件的指针移到开头:
users = open("users.txt", 'r') with open("email.txt", 'r') as f: for email in f: target_email = email.strip() users.seek(0) # 重置文件指针到文件开头 for line in users.readlines(): if line.startswith(target_email): user_id = line.strip().split(':')[1] print(user_id) users.close() # 手动关闭文件
说明
方案1更高效,尤其是文件内容较多时,字典查找是O(1)的时间复杂度;方案2每次都要重读整个users.txt,效率较低。另外,使用with语句管理文件会自动关闭文件,比直接open更安全,避免资源泄漏。
内容的提问来源于stack exchange,提问作者Jim Halpert
相关产品推荐
相关产品推荐

