代码之家  ›  专栏  ›  技术社区  ›  Rasec Malkic

以类似矩阵的形式存储列表中的值

  •  0
  • Rasec Malkic  · 技术社区  · 3 年前

    我有以下清单 L 为此,我试图将值存储在定位每个值的“行”逻辑中 在字典给出的位置 HeadersPositions .

    这是我当前的代码,我尝试过 while element[0] != "V": 以便在获取最后一个标题后更改为下一行 V 对于每个“行”,但我得到了一个无限循环,然后我改为 if element[0] != "V": 以便控制何时切换到下一行,但仅存储在列表中 row ,收割台的第一个位置 B

    L = [
        ['B', 3], 
        ['T', 0], 
        ['N', 5], 
        ['V', 2], 
        ['N', 1], 
        ['V', 4],
        ['B', 7], 
        ['T', 2], 
        ['N', 9], 
        ['V', 1], 
        ['B', 1], 
        ['N', 8], 
        ['V', 3]
    ]
    
    HeadersPositions = {'B': 0, 'T': 1, 'N': 2, 'V': 3}
    
    rows = []
    row=[None]*len(HeadersPositions)
    for element in L:
        if element[0] != "V":
            row.insert(HeadersPositions[element[0]], element[1])
        rows.append(row)
    

    我想要的输出是

    Out = [
            [3,0,5,2], 
            [none,none,1,4], 
            [7,2,9,1], 
            [1,none,8,3],         
        ]      
    

    看起来像桌子是这样的:

    B   T   N   V
    3   0   5   2
            1   4
    7   2   9   1  
    1       8   3
    
    1 回复  |  直到 3 年前
        1
  •  0
  •   Grismar    3 年前

    已重命名 L data 自从 L 是大写字母和 l 也不是推荐的变量名):

    data = [
        ['B', 3], 
        ['T', 0], 
        ['N', 5], 
        ['V', 2], 
        ['N', 1], 
        ['V', 4],
        ['B', 7], 
        ['T', 2], 
        ['N', 9], 
        ['V', 1], 
        ['B', 1], 
        ['N', 8], 
        ['V', 3]
    ]
    
    headers_positions= {'B': 0, 'T': 1, 'N': 2, 'V': 3}
    rows = []
    while data:
        rows.append([
            data.pop(0)[1] if data and data[0][0] == h else None
            for h in headers_positions.keys()
        ])
    
    print(rows)
    

    输出

    [[3, 0, 5, 2], [None, None, 1, 4], [7, 2, 9, 1], [1, None, 8, 3]]
    

    注意:这是忽略的值 HeadersPositions ,如果可以的话,你可能应该在那里使用一个列表。

    否则

    headers_positions = {'B': 0, 'T': 1, 'N': 2, 'V': 3}
    headers = [k for k, v in sorted(headers_positions.items(), key=lambda h: h[1])]
    rows = []
    while data:
        rows.append([
            data.pop(0)[1] if data and data[0][0] == h else None
            for h in headers
        ])
    

    编辑:你要求对它的实际工作原理进行一些解释。

    在外部:

    while data:
        rows.append([
            ...
        ])
    

    只要 数据 不为空,循环将继续添加新行。请注意 数据 它本身正在被清空。如果需要 数据 要保持不变,您可以:

    c_data = list(data)
    while c_data:
        rows.append([
            ...
        ])
    

    这将创建的副本 数据 ,你会使用 c_data 循环内部。

    正在添加为行的列表:

        [
            data.pop(0)[1] if data and data[0][0] == h else None
            for h in headers_positions.keys()
        ]
    

    • 从中弹出第一个元素 数据 ,如果还有数据( if data ) 第一个元素与当前标头匹配( data[0][0] == h ). data.pop(0) 从中删除第一个元素 数据 并且只有值 [1] 然后用于填充列表。
    • 如果没有剩下的数据,或者数据中剩下的第一个值与标头不匹配,它会添加 None 改为列表
    • 并且它按顺序对报头列表中的每个报头都这样做。

    所以,在第一行,它按顺序找到B、T、N和V的值,所以它们都被弹出并相加。在第二行,它在开始时找不到B的值,所以它添加了 没有一个 ,也找不到t,所以另一个 没有一个 被添加,但它在开始时确实找到了N,所以它会在列表中弹出1,等等。

    这种为每一行构建列表的方式被称为“列表理解”。和 while data if数据 利用的真实性 list ,空列表为 False ,而非空列表为 True .

        2
  •  0
  •   amisotcm    3 年前

    你可以试试这个基本的解决方案

    def function(L, keylist):
        final_out = []
        out = []
        for i in range(len(L)):
            k = len(out)
            key = L[i][0]
            value = L[i][1]
    
            while key != keylist[k]:
                out.append(None)
                k = k + 1
    
            out.append(value)
            if len(out) == len(keylist):
                final_out.append(out)
                out = []
    
        return final_out
    

    后果

    keylist = ["B", "T", "N", "V"]
    print(function(L, keylist))
    
    [[3, 0, 5, 2], [None, None, 1, 4], [7, 2, 9, 1], [1, None, 8, 3]]