基于CSV手机号条件过滤数据的Python代码异常排查
问题排查与修正代码
原代码存在的问题
- 数据库读取器被耗尽:
database_reader是一次性迭代器,第一次遍历后就没有数据了,后续的unsubscribed_row循环无法再读取数据库内容。 - 类型不匹配的比较:
db_row[4]是字符串类型的手机号,但unsubscribed_row是csv.reader返回的列表(比如['+41620984573']),直接比较永远不会相等。 - 逻辑效率低下且错误:嵌套循环会导致数据库行被多次写入(每次不匹配退订项时都写一次),而且没有过滤退订列表中的邮箱。
修正后的代码
import csv if __name__ == '__main__': # 收集所有需要退订的手机号(忽略邮箱) unsubscribed_phones = set() with open('EMRG_Unsubscribed.csv', newline='') as unsubscribed_file: reader = csv.reader(unsubscribed_file) next(reader) # 跳过表头 for row in reader: entry = row[0].strip() # 获取退订项并去除首尾空格 # 根据格式判断是否为手机号(示例中以+开头,可按需调整规则) if entry.startswith('+'): unsubscribed_phones.add(entry) # 处理数据库,移除匹配手机号的行 with open('EMRG_ Database.csv', newline='') as database_file, \ open('EMRG_Updated_Database.csv', 'w', newline='') as updated_file: db_reader = csv.reader(database_file) db_writer = csv.writer(updated_file) # 写入表头 header = next(db_reader) db_writer.writerow(header) # 遍历数据库每一行 for row in db_reader: phone = row[4].strip() # 获取当前行手机号并去除空格 if phone not in unsubscribed_phones: db_writer.writerow(row)
代码说明
- 集合存储退订手机号:集合的查找操作是O(1),比循环遍历效率高很多。
- 过滤退订列表中的邮箱:通过判断是否以
+开头(可根据实际手机号格式调整规则),只保留有效手机号到集合中。 - 一次性读取数据库:避免迭代器耗尽问题,确保每一行只被处理一次。
- 处理表头:明确跳过退订列表的表头,并将数据库表头写入输出文件。
- 去除空格:使用
strip()避免因首尾空格导致的匹配失败(比如文件中存在多余空格的情况)。
内容的提问来源于stack exchange,提问作者joo
相关产品推荐
相关产品推荐

