首页 > 解决方案 > Python:通过映射另一个数据的字段生成列表

问题描述

使用 Python3.x,我有生成 X 的代码,其中包含用逗号分隔的单引号中的子列表列表,我的任务是将一些“X”字段映射到“Y”示例列表,“Y”的输出相乘按“X”中的行数

X = 
[
'sequence:1, MAP:A, num1:1, num2:2, num3:3', 
'sequence:2, num1:10, num2:20, MAP:B, num3:30',
'sequence:3, num1:100, MAP:C, num2:200, num3:300'
]

Y = ['VEQ','1','MAP-replacehere','2','num1-replacehere',]

所需输出:

'VEQ','1','A','2','1'      ##col3,5 replaced from MAP:A and num1:1
'VEQ','1','B','2','10'     ##col3,5 replaced from MAP:B and num1:10
'VEQ','1','C','2','100'    ##col3,5 replaced from MAP:C and num1:100

(“Y”的其他字段保持不变,只有 col3,5 从“X”映射)

为了描述上述输出,

我已经生成了 3 次“Y”样本行,因为 X 有 3 行。

我已经用“X”中的“MAP”的字典字段替换了“Y”第 3 列(“X”内的 MAP 的列号不固定。它可以在第 1 列、第 2 列或第 3 列中……)

我已经用“X”中的“num1”的dict字段替换了“Y”第5列(“X”内的num1的列号不固定)**

我尝试过的: 我在下面有一个示例,该示例适用于 X 示例,它不是 dict 格式.. 并且列字段是固定的..

X = ['sequence, A, 1, 2, 3', 
     'sequence, B, 10, 20, 30', 
     'sequence, C, 100, 200, 300']

Y = ['VEQ','1','map','2','cap',]

def replace(X,Y,position_list):
    result = []
    for x in X:
        x = x.split(',')
        x = [t.strip() for t in x]
        temp = Y.copy()
        for pos in position_list:
            temp[pos[0] - 1] = x[pos[1] - 1]
        result.append(temp)
    return result

replace(X,Y,[(3,2),(5,3)]) #####this is working for fixed columns of X. 

能否请您帮忙,如果可以修改此代码以获得所需的结果,或者是否有任何其他方法可以实现这一点..

提前致谢..

标签: pythonpython-3.x

解决方案


您必须首先将每一行从 X 转换为字典。这必须手动完成,因为您拥有的既不是有效的 json 也不是eval可用的字符串。

然后对于 X 中的每个字段,如果值以-replacehere您结尾,则将其替换为从 X 中的行构建的字典中的前缀值。

作为一个 Python 函数,它可能看起来像:

import re

X = [
'sequence:1, MAP:A, num1:1, num2:2, num3:3', 
'sequence:2, num1:10, num2:20, MAP:B, num3:30',
'sequence:3, num1:100, MAP:C, num2:200, num3:300'
]

Y = ['VEQ','1','MAP-replacehere','2','num1-replacehere',]

def replace(x, y):
    # prepare splitting of rows from X
    splitter = re.compile(r'\s*,\s*')

    #prepare Y processing
    rep = '-replacehere'
    length = len(rep)

    y2 = [(i[:-length], True) if  i.endswith(rep) else (i, False)
          for i in y]
    # with the example Y it gives [('VEQ', False), ('1', False), ('MAP', True), 
    #                              ('2', False), ('num1', True)]

    # run...
    for line in X:
        d = { m[0]: m[1] for m in [
            item.split(':', 1) for item in splitter.split(line)]}
        print(*[repr(d[i[0]] if i[1] else i[0]) for i in y2])

然后您可以调用该函数:

>>> replace(X, Y)
'VEQ' '1' 'A' '2' '1'
'VEQ' '1' 'B' '2' '10'
'VEQ' '1' 'C' '2' '100'

推荐阅读