如何定位pyodbc查询返回列表中的Decimal数据类型位置?
问题:识别pyodbc返回结果中的Decimal类型位置并四舍五入
使用pyodbc从SQL查询返回的数据中包含Decimal类型(例如Decimal('4117.0000')),需要找到这些Decimal类型的位置并将其四舍五入到百分位。尝试了以下代码:
import pyodbc from decimal import Decimal # 已连接到SQL数据库,获取表数据 mssql_table = list(cursor_mssql.fetchall()) # 遍历行并转换为列表 for i in range(len(mssql_table)): mssql_row = list(mssql_table[i])
示例行数据:[1, 363, datetime.datetime(2022, 9, 27, 15, 36, 27), 'JONH', 70, 362, Decimal('4117.0000'), 'Bill 27', False, None],其中Decimal类型位于索引6的位置。
用于查找位置的代码:
# 查找列表中的Decimal数据类型位置 if(Decimal() in mssql_row): decimal_pos = mssql_row.index(Decimal())
但实际运行时,预期decimal_pos为6却返回8;在无Decimal类型的行[1, 'United States', 'US', 167, False, 0, True]中,该判断返回True且decimal_pos为4,明显错误识别了布尔类型。请问问题出在哪里?有什么更好的实现方法?
解答
错误原因
你用Decimal()创建了一个值为Decimal(0)的对象,然后用in和index()去匹配列表中的元素。在Python中,布尔类型是整数的子类,False等价于0,因此Decimal(0) == False会返回True——这就导致代码把列表中的False误判为匹配的Decimal对象,从而返回错误的索引位置。
正确实现方法
应该通过类型检查来识别Decimal对象,而不是值匹配。可以用isinstance()函数判断元素类型,结合enumerate()同时获取索引和元素值:
from decimal import Decimal # 遍历行时,收集所有Decimal类型的索引位置 for i in range(len(mssql_table)): mssql_row = list(mssql_table[i]) # 获取所有Decimal类型的位置 decimal_positions = [idx for idx, val in enumerate(mssql_row) if isinstance(val, Decimal)] # 对每个Decimal值进行百分位四舍五入 for pos in decimal_positions: # quantize(Decimal('0.00')) 实现四舍五入到百分位 mssql_row[pos] = mssql_row[pos].quantize(Decimal('0.00')) # 处理后的行可以继续后续操作 # ...
说明
isinstance(val, Decimal)会严格检查元素是否是Decimal类型的实例,不会把布尔值、整数等其他类型误判。enumerate()可以同时拿到元素的索引和值,方便收集所有符合条件的位置。quantize(Decimal('0.00'))是Decimal类型自带的四舍五入方法,能精准控制小数位数。
内容的提问来源于stack exchange,提问作者Bill Barnes
相关产品推荐
相关产品推荐

