如何用数学公式简化Python分块遍历逻辑,移除loop变量?
优化分块匹配字典值的Python代码
需求:不借助额外库,将列表lst按8条为一组分块,为1-8、9-16、17-24等区间的记录匹配字典dct的对应值。现有代码通过loop变量实现逻辑,希望移除该变量及相关判断语句,用更简洁易读的数学公式替代record-loop,同时避免((record - 1) % 8) + 1这类不够直观的写法。
现有代码
dct = {1:'one', 2:'two', 3:'three', 4:'four', 5:'five', 6:'six', 7:'seven', 8:'eight'} lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] loop = 0 for record in lst: print(f'record id: {record:<10} dct id: {record-loop:<10} dct value: {dct.get(record - loop)}') if record % 8 == 0: loop += 8 print('--- loop finished ---')
当前输出
record id: 1 dct id: 1 dct value: one record id: 2 dct id: 2 dct value: two record id: 3 dct id: 3 dct value: three record id: 4 dct id: 4 dct value: four record id: 5 dct id: 5 dct value: five record id: 6 dct id: 6 dct value: six record id: 7 dct id: 7 dct value: seven record id: 8 dct id: 8 dct value: eight --- loop finished --- record id: 9 dct id: 1 dct value: one record id: 10 dct id: 2 dct value: two record id: 11 dct id: 3 dct value: three record id: 12 dct id: 4 dct value: four record id: 13 dct id: 5 dct value: five record id: 14 dct id: 6 dct value: six record id: 15 dct id: 7 dct value: seven record id: 16 dct id: 8 dct value: eight --- loop finished --- record id: 17 dct id: 1 dct value: one record id: 18 dct id: 2 dct value: two record id: 19 dct id: 3 dct value: three record id: 20 dct id: 4 dct value: four record id: 21 dct id: 5 dct value: five record id: 22 dct id: 6 dct value: six record id: 23 dct id: 7 dct value: seven record id: 24 dct id: 8 dct value: eight --- loop finished ---
注意:直接使用record%8会得到0而非8,不符合需求,因此需要更合适的数学公式。
优化方案
方案1:整除计算组内位置
用record - 8 * ((record - 1) // 8)替代record-loop,逻辑是先算出当前记录所在的组(从0开始计数),再用记录值减去组的起始值(组号×8),得到组内1-8的位置。
优化后代码:
dct = {1:'one', 2:'two', 3:'three', 4:'four', 5:'five', 6:'six', 7:'seven', 8:'eight'} lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] for record in lst: dct_id = record - 8 * ((record - 1) // 8) print(f'record id: {record:<10} dct id: {dct_id:<10} dct value: {dct.get(dct_id)}') if dct_id == 8: print('--- loop finished ---')
方案2:模运算变种
利用(record % 8) or 8,当记录是8的倍数时,record%8结果为0,or运算会返回8;其他情况返回模运算的结果1-7,正好符合需求。
优化后代码:
dct = {1:'one', 2:'two', 3:'three', 4:'four', 5:'five', 6:'six', 7:'seven', 8:'eight'} lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] for record in lst: dct_id = (record % 8) or 8 print(f'record id: {record:<10} dct id: {dct_id:<10} dct value: {dct.get(dct_id)}') if dct_id == 8: print('--- loop finished ---')
两个方案都移除了loop变量和相关判断,代码更简洁,逻辑清晰易读。
内容的提问来源于stack exchange,提问作者Roman Toasov
相关产品推荐
相关产品推荐

