提取UNV文件边界节点数据时遇IndexError索引越界错误求助
UNV文件边界节点数据提取的IndexError问题修复
问题背景
编写Python代码提取UNV文件数据时触发IndexError: list index out of range错误,目标是提取文件1270-1357行中SOURCE和WALLS两个边界组的边界节点数据。
原代码
from collections import defaultdict import numpy as np from tqdm import tqdm import os, sys import math # This is the UNV file input = open('Mesh_5x5x5x.unv','r') output = open('co-ordinates.txt','w') output2 = open('nodes.txt','w') output3 = open('connectivity.txt','w') output4 = open('boundary_2_6.txt','w') data = input.readlines() print(len(data)) input.seek(0) x= [] y=[] z=[] node=[] conn1 = [] conn2 = [] conn3 = [] conn4 = [] boundary = 0 boundary_list = [] boundary_names = defaultdict(list) boundary_names_2_5 = defaultdict(list) boundary_index = [] # READING THE DATA FROM UNV FILE for line in data: if line.strip().lstrip() == '2411': start_index = data.index(line) if line.strip().lstrip() == '2412': stop_index = data.index(line) # READIG THE COORDINATE DATA FROM UNV FILE for i in range(start_index+1,stop_index-2,2): l1 = data[i].strip('\n \t').lstrip().split() node.append(l1[0]) l2 = data[i+1].strip('\n \t').lstrip().split() x.append(l2[0]) y.append(l2[1]) z.append(l2[2]) # READING CONNECTIVITY OF FACES for line in data: if line.strip().lstrip() == '2412': start_index = data.index(line) if line.strip().lstrip() == '2467': stop_index = data.index(line) for i in range(start_index+1,stop_index,1): if len(data[i].strip().lstrip().split())==4: conn1.append(data[i].strip().lstrip().split()[0]) conn2.append(data[i].strip().lstrip().split()[1]) conn3.append(data[i].strip().lstrip().split()[2]) conn4.append(data[i].strip().lstrip().split()[3]) # READ BUNDARY INFORMATION: ELEMENTS AND NODES: # HERE I AM PARTICULARLY INTERESTED IN EXTRACTING NODE DATA WHICH IS CONTAINED IN THE LAST GROUPS : SOURCE AND WALLS (LINES 1270 TO 1357) for i in range(stop_index+1,len(data),1): if data[i].strip().lstrip()[0].isalpha() == True: print('DDD:',i,stop_index+1,len(data)) boundary_names[data[i].strip().lstrip()] boundary_names_2_5[data[i].strip().lstrip()] boundary = boundary+0.5 boundary_list.append(data[i].strip().lstrip()) boundary_index.append(i) print(boundary_list) print(boundary_index) print(len(boundary_index)) bnd_index = boundary_index[len(boundary_index)//2:] bnd = len(bnd_index) print('bnd',bnd) for l in range(bnd): print(l) print(boundary_index[l+2]) print(boundary_index[l+1]) lines = (boundary_index[l+3]-boundary_index[l])-3 print("lines=",lines) for k in range(lines): p = data[bnd_index[l]+1+k].split() print("p=",p, len(p)) if (len(p)>1): p = data[bnd_index[l]+1+k].split() boundary_names_2_5[data[bnd_index[l]].strip()].append(p[1]) boundary_names_2_5[data[bnd_index[l]].strip()].append(p[5])
报错信息
p= ['7', '14', '0', '0', '7', '15', '0', '0'] 8 p= ['7', '16', '0', '0', '7', '7', '0', '0'] 8 p= ['7', '29', '0', '0', '7', '30', '0', '0'] 8 p= ['7', '31', '0', '0', '7', '32', '0', '0'] 8 p= ['7', '1', '0', '0', '7', '5', '0', '0'] 8 p= ['-1'] 1 Traceback (most recent call last): File ~\anaconda3\lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec exec(code, globals, locals) File c:\jnanadeepti\prasad\coding2023\lbm-python\3d\3d-flow\readunv\read_unv-test.py:88 p = data[bnd_index[l]+1+k].split() IndexError: list index out of range
问题分析
- 硬编码偏移导致越界:原代码中用
boundary_index[l+3]-boundary_index[l]-3计算行数,当l是bnd的最后一个元素时,l+3会超出boundary_index的长度,导致lines计算错误,循环k时索引超出data列表范围。 - 边界组范围判断错误:没有动态判断每个边界组的结束位置,而是依赖固定偏移,无法适配文件结构的变化。
修复方案
修改边界节点数据提取的循环逻辑,动态获取每个边界组的起始和结束索引,避免硬编码偏移:
# 替换原代码中最后一段for循环(从for l in range(bnd):开始的部分) for idx, current_start in enumerate(bnd_index): # 获取当前边界组名称 group_name = data[current_start].strip() # 确定当前组的结束索引:最后一组用文件末尾,否则用下一个组的起始索引 if idx < len(bnd_index) - 1: current_end = bnd_index[idx + 1] else: current_end = len(data) # 遍历当前组内的所有行,跳过空行 for line_idx in range(current_start + 1, current_end): line = data[line_idx].strip() if not line: continue p = line.split() print(f"p={p}, len={len(p)}") if len(p) > 1: # 提取目标节点数据 boundary_names_2_5[group_name].append(p[1]) boundary_names_2_5[group_name].append(p[5])
修复要点
- 用
enumerate遍历bnd_index,动态获取每个边界组的起始位置,以及下一个组的起始位置作为结束标记。 - 最后一组直接以
len(data)作为结束索引,确保不会超出列表范围。 - 跳过空行,避免无效数据的干扰。
内容的提问来源于stack exchange,提问作者prasadji
相关产品推荐
相关产品推荐

