Python中for循环遍历同一元素两次问题及代码调试求助
问题排查:循环中看似重复遍历元素的原因及解决办法
嘿,我一眼就揪出问题所在了——你用来打印索引的bulkdata.index(datum)就是让你产生“同一元素被遍历两次”错觉的罪魁祸首!
为什么会出现这种现象?
list.index(item)方法的逻辑是返回列表中第一个匹配该元素的位置索引。如果你的bulkdata列表里存在两个内容完全相同的字典(比如两个datum的timestamp、sensor_type、value完全一致),那么对于这两个不同的元素,index()会返回同一个索引值。这就导致你打印出来的索引重复,看起来像是同一个元素被遍历了两次,但实际上循环是在正常遍历列表里的每一个元素的。
你可以做个小验证:在循环里加上print(id(datum)),打印每个元素的内存地址,就能发现每次遍历的都是不同的对象,只是内容重复而已。
快速解决办法
改用enumerate()来遍历,它能同时拿到正确的索引和对应的元素,完美避开index()的坑:
@app.task() def add_data_bulk(source_uuid, bulkdata): print(type(bulkdata)) print(type(bulkdata[1])) print(len(bulkdata)) # 用enumerate获取正确的索引和元素 for idx, datum in enumerate(bulkdata): print("Datum {}: source_uuid: {}, timestamp: {}".format(idx, source_uuid, datum["timestamp"])) new_datum = data.Datum(source_uuid, datum["sensor_type"], datum["timestamp"], datum["value"]) session = db_setup.get_db_session() session.add(new_datum) session.commit() return None
额外的优化建议
另外还有个小细节可以优化:你现在在循环里每次都创建新的数据库会话并立刻提交,这会产生不必要的数据库连接开销。建议把会话的创建、提交/回滚逻辑移到循环外面,效率会更高:
@app.task() def add_data_bulk(source_uuid, bulkdata): print(type(bulkdata)) print(type(bulkdata[1])) print(len(bulkdata)) session = db_setup.get_db_session() try: for idx, datum in enumerate(bulkdata): print("Datum {}: source_uuid: {}, timestamp: {}".format(idx, source_uuid, datum["timestamp"])) new_datum = data.Datum(source_uuid, datum["sensor_type"], datum["timestamp"], datum["value"]) session.add(new_datum) # 所有元素添加完成后统一提交 session.commit() except Exception as e: # 出错时回滚事务 session.rollback() raise e finally: # 无论成功失败都关闭会话 session.close() return None
内容的提问来源于stack exchange,提问作者Gasp0de
相关产品推荐
相关产品推荐

