我正在尝试编写一个Python脚本,该脚本将读取通过CSV文件输入的一系列负载,并返回生成的力矢量。 CSV的格式为:
x,y,z,load_in_x,load_in_y,load_in_z
u,v,w,load_in_x,load_in_y,load_in_z
...
这是脚本:
# Fastener class containing an ID, location in space, and load vector
class Fastener(object):
"""A collection of fasteners"""
noOfFstnrs = 0
def __init__(self,xyz,load):
self.xyz = xyz
self.load = load
Fastener.noOfFstnrs += 1
self.fastID = Fastener.noOfFstnrs
def __repr__(self):
return """Fastener ID: %s
Location: %s
Load: %s""" % (self.fastID, self.xyz, self.load)
# Request the mapping CSV file from the user. The format should be:
# x,y,z,load_in_x,load_in_y,load_in_z
path = input("Fastener mapping file: ")
with open(path,"r") as inputFile:
inputLines = inputFile.readlines()
# Create a list of Fastener objects from each line in the mapping file
F = []
for line in range(len(inputLines)):
inputLines[line] = inputLines[line].strip('\n')
inputLines[line] = inputLines[line].split(",")
location = [float(i) for i in inputLines[line][:3]]
load = [float(i) for i in inputLines[line][3:]]
F.append(Fastener(location,load))
# Function to sum all fastener loads and return the resulting linear force
# vector
def sumLin(fastenerList):
xSum = 0
ySum = 0
zSum = 0
for i in fastenerList:
xSum += fastenerList[i].load[1]
ySum += fastenerList[i].load[2]
zSum += fastenerList[i].load[3]
linVector = [xSum, ySum, zSum]
return linVector
# Print
print(sumLin(F))
当我运行它时,我不断收到以下错误:
Traceback (most recent call last):
File "bolt_group.py", line 49, in <module>
print(sumLin(F))
File "bolt_group.py", line 42, in sumLin
xSum += fastenerList[i].load[1]
TypeError: list indices must be integers, not Fastener
我尝试将循环索引i
更改为int(i)
,但它仍然给我带来了问题。如果我像下面那样手动添加它们就没有问题。
xSum = F[1].load[1] + F[2].load[1] + F[3].load[1]
答案 0 :(得分:4)
fastenerList[i].load[1]
i
是Fastener
对象,不是整数。因此调用fastenerList[i]
无效;你应该传递一个整数。变化:
for i in fastenerList: # 'i' is a 'Fastener' object
到
for i in range(len(fastenerList)): # 'i' is an integer
答案 1 :(得分:2)
我认为更加pythonic的方式是迭代紧固件列表:
for fastener in fastenerList:
xSum += fastener.load[0]
ySum += fastener.load[1]
zSum += fastener.load[2]
如果你希望你的代码非常快,你可以将csv数据加载到numpy.ndarray中并让numpy进行求和(避免在python中使用多个for循环)但是如果速度你会很好用这种方法并不重要。
答案 2 :(得分:2)
可以对您的代码进行各种改进。正如jochen所说,直接迭代列表而不是使用索引更像是Pythonic。该原则也可以应用于填充Fastener对象列表的代码。
with open(path,"r") as inputFile:
# Create a list of Fastener objects from each line in the mapping file
F = []
for line in inputLines:
data = [float(i) for i in line.strip().split(",")]
location = data[:3]
load = data[3:]
F.append(Fastener(location, load))
# Function to sum all fastener loads and return the resulting linear force
# vector
def sumLin(fastenerList):
xSum = 0
ySum = 0
zSum = 0
for fastener in fastenerList:
xSum += fastener.load[0]
ySum += fastener.load[1]
zSum += fastener.load[2]
linVector = [xSum, ySum, zSum]
return linVector
但是,我们可以使用内置的zip
函数进一步压缩sumLin
函数:
def sumLin(fastenerList):
loads = [fastener.load for fastener in fastenerList]
return [sum(t) for t in zip(*loads)]
显然,我的代码未经测试,因为您没有向我们提供任何样本数据...