You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

提取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

问题分析

  1. 硬编码偏移导致越界:原代码中用boundary_index[l+3]-boundary_index[l]-3计算行数,当l是bnd的最后一个元素时,l+3会超出boundary_index的长度,导致lines计算错误,循环k时索引超出data列表范围。
  2. 边界组范围判断错误:没有动态判断每个边界组的结束位置,而是依赖固定偏移,无法适配文件结构的变化。

修复方案

修改边界节点数据提取的循环逻辑,动态获取每个边界组的起始和结束索引,避免硬编码偏移:

# 替换原代码中最后一段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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 21:28:15