【问题标题】:Split list of lists into lists knowing index of end将列表拆分为知道结束索引的列表
【发布时间】:2021-10-02 06:14:25
【问题描述】:

在互联网上多次尝试和研究将列表列表拆分为单独的列表后,我遇到了麻烦。

我有以下File 包含由开始和结束序列分隔的载荷工况。该文件可能有 4 或 n 个载荷工况,具有 10 或 n 个站,因此无论其数量如何,代码都应以相同的方式运行。我的目标是为每个负载情况创建一个 numpy 数组,因此在本例中为 4 个数组。

我首先读取文件并检测开始和结束序列,添加关键字“fin”以了解负载情况的分离。

def read(filename): 
with open(filename,'r') as f : 
    copy = False
    L=[]
    for line in f:
        if line.strip() == "BEGIN":
            copy = True
            continue
            
        elif line.strip() == "END":
            copy = False
            L.append(['fin'])
            
            continue
        
        
        elif copy :
            # print([float(i) for i in line.split()])
            L.append(line.split())
   
        
return(L)

我的问题从这里开始,我找不到一种方法来分离这个大列表 L 以获得 4 个负载案例列表或数组。我通过获取“fin”关键字的索引进行了尝试,但我只能打印负载情况,而不是将它们放在单独的变量中,因为 Python for 循环不允许在每次迭代中动态创建新变量。

index = [i for i, value in enumerate(L) if value == ['fin']]
    print(index)
    print(L[0:index[0]])
    for i in range(len(index)-1):
        print(np.array(L[index[i]+1:index[i+1]]))

希望这很清楚,谢谢!

$-Station---$-coord(m)--$Fx---------$Fy---------$Fz---------$Mx---------$My---------$Mz---------$
BEGIN
         1.0         1.0        10.0        20.0        30.0         0.0       210.0      -140.0
         1.0         2.0        20.0        40.0        60.0         0.0       390.0      -260.0
         1.0         3.0        30.0        60.0        90.0         0.0       540.0      -360.0
         1.0         4.0        40.0        80.0       120.0       180.0       660.0      -500.0
         1.0         5.0        50.0       100.0       150.0       540.0       750.0      -680.0
         1.0         6.0        60.0       120.0       180.0       540.0       810.0      -720.0
         1.0         7.0        70.0       140.0       210.0       540.0       840.0      -740.0
         1.0         8.0        30.0        60.0        90.0         0.0       -90.0        60.0
         1.0         9.0        20.0        40.0        60.0         0.0       -90.0        60.0
         1.0        10.0        10.0        20.0        30.0         0.0       -60.0        40.0
END
$-Station---$-coord(m)--$Fx---------$Fy---------$Fz---------$Mx---------$My---------$Mz---------$
BEGIN
         1.0         1.0        20.0        20.0        30.0         0.0       210.0      -140.0
         1.0         2.0        30.0        40.0        60.0         0.0       390.0      -260.0
         1.0         3.0        40.0        60.0        90.0         0.0       540.0      -360.0
         1.0         4.0        50.0        80.0       120.0       180.0       660.0      -500.0
         1.0         5.0        60.0       100.0       150.0       540.0       750.0      -680.0
         1.0         6.0        70.0       120.0       180.0       540.0       810.0      -720.0
         1.0         7.0        80.0       140.0       210.0       540.0       840.0      -740.0
         1.0         8.0        30.0        60.0        90.0         0.0       -90.0        60.0
         1.0         9.0        20.0        40.0        60.0         0.0       -90.0        60.0
         1.0        10.0        10.0        20.0        30.0         0.0       -60.0        40.0
END
$-Station---$-coord(m)--$Fx---------$Fy---------$Fz---------$Mx---------$My---------$Mz---------$
BEGIN
         1.0         1.0        30.0        20.0        30.0         0.0       210.0      -140.0
         1.0         2.0        40.0        40.0        60.0         0.0       390.0      -260.0
         1.0         3.0        50.0        60.0        90.0         0.0       540.0      -360.0
         1.0         4.0        60.0        80.0       120.0       180.0       660.0      -500.0
         1.0         5.0        70.0       100.0       150.0       540.0       750.0      -680.0
         1.0         6.0        80.0       120.0       180.0       540.0       810.0      -720.0
         1.0         7.0        90.0       140.0       210.0       540.0       840.0      -740.0
         1.0         8.0        30.0        60.0        90.0         0.0       -90.0        60.0
         1.0         9.0        20.0        40.0        60.0         0.0       -90.0        60.0
         1.0        10.0        10.0        20.0        30.0         0.0       -60.0        40.0
END
$-Station---$-coord(m)--$Fx---------$Fy---------$Fz---------$Mx---------$My---------$Mz---------$
BEGIN
         1.0         1.0        40.0        20.0        30.0         0.0       210.0      -140.0
         1.0         2.0        50.0        40.0        60.0         0.0       390.0      -260.0
         1.0         3.0        60.0        60.0        90.0         0.0       540.0      -360.0
         1.0         4.0        70.0        80.0       120.0       180.0       660.0      -500.0
         1.0         5.0        80.0       100.0       150.0       540.0       750.0      -680.0
         1.0         6.0        90.0       120.0       180.0       540.0       810.0      -720.0
         1.0         7.0       100.0       140.0       210.0       540.0       840.0      -740.0
         1.0         8.0        30.0        60.0        90.0         0.0       -90.0        60.0
         1.0         9.0        20.0        40.0        60.0         0.0       -90.0        60.0
         1.0        10.0        10.0        20.0        30.0         0.0       -60.0        40.0
END

【问题讨论】:

  • 请将内容粘贴到这里
  • 你的意思是代码?
  • @Damelko 他的意思是文件中的数据
  • 我不清楚您所说的“4 或 n 个载荷工况,有 10 个或 n 个站点”是什么意思。

标签: python arrays list


【解决方案1】:

如果我正确理解您的问题,那么列表列表可能会有所帮助。例如:-

我创建了一个如下所示的文件:-

开始
一个

C
结束

开始
X
是的
Z
结束
呵呵

...然后...

L = []

with open('/Users/andy/begin.txt') as infile:
    IL = None
    for line in infile:
        ls = line.rstrip('\n')
        if ls == 'BEGIN':
            IL = []
        elif ls == 'END':
            L.append(IL)
            IL = None
        elif IL is not None:
            IL.append(ls)

print(L)

...会给出这个结果...

[['A', 'B', 'C'], ['X', 'Y', 'Z']]

此代码可能不可靠,因为它假定 END 总是成功地出现 BEGIN

【讨论】:

  • 谢谢,但是稍后当我想将此列表列表分成不同的列表或数组时,我会遇到同样的问题...预期结果是 L1 = [A,B,C] 和L2 = [X,Y,Z] 螺母 如果有 100 个载荷工况,我无法手动执行此操作。
  • 但是使用此代码和您的示例,L1 等效于 L[0]。我不确定我是否理解您的问题
  • 是的,我可以使用您的代码访问我在 L[i] 中的负载案例。但是我找不到将所有这些 L[i] 放在其他变量中的方法,因为我真的需要单独操作它们。
【解决方案2】:

您可以使用生成器并删除“fin”和copy 变量。

在下面的生成器函数中,请注意yield 语句,它会一个一个地“产生”负载情况,而不退出函数。这就是使这个函数成为生成器的原因。

def read_loadcases(filename):
    loadcase = []
    # NOTE: lines before first BEGIN will be collected but thrown away
    with open(filename,'r') as f :
        for line in f:
            if line.strip() == "BEGIN":
                loadcase = []
                continue
            if line.strip() == "END":
                yield loadcase
                continue
            loadcase.append(line.split())

上面的生成器函数依赖于将 BEGIN 和 END 可靠地放置在文件中,将每个负载情况包含在内。输出中不需要“fin”标记,因为生成器一次只输出一个载荷工况。

您可以按如下方式使用上述生成器:

for loadcase in read_loadcases(filename):
    do_something_with(loadcase)

例如:

for loadcase in read_loadcases(filename):
    print(len(loadcase))

或:

for lc in read_loadcases(filename):
    loadcase = np.array(lc)
    # process loadcase using numpy facilities

无论原始文件中有多少载荷工况,这都会起作用。只有当前的工况在内存中。

如果您想将载荷工况放在单独的命名变量中(例如,前 4 个载荷工况很特殊),您可以执行以下操作:

loadcase_iterator = read_loadcases(filename)
loadcase1 = loadcase_iterator.__next__()
loadcase2 = loadcase_iterator.__next__()
loadcase3 = loadcase_iterator.__next__()
loadcase4 = loadcase_iterator.__next__()

如果您需要每个工况的最后一个索引,可以使用len(loadcase3) - 1 例如。

其余的荷载工况可以使用:

for loadcase in loadcase_iterator:
    do_something_with(loadcase)

这将从loadcase4 之后的下一个工况开始。

如果您要处理大文件,那么学习生成器和迭代器会为您带来很多回报。

This article 介绍了一个读取大文件的示例,可能会有所帮助。

David Beazley 的Generator Tricks for System Programmers 是任何处理大文件的人的经典教程。本教程的前几页应该让您开始使用生成器和迭代器。

【讨论】:

    猜你喜欢
    • 2016-09-01
    • 1970-01-01
    • 2013-09-05
    • 2020-01-14
    • 2022-12-20
    • 2020-05-02
    • 2018-12-08
    • 1970-01-01
    相关资源
    最近更新 更多