【问题标题】:Create Product Permutation of irregularly Nested Loop创建不规则嵌套循环的产品排列
【发布时间】:2020-11-23 23:44:01
【问题描述】:

抱歉冗长的解释,我有两个嵌套列表,一个包含一系列字段的参考值,称为dl,另一个包含字段名称,称为k_all_tbl。它们看起来像下面这样:

dl = [[['Aegon', 'Aviva', 'HSBC', 'Zurich'], 'S_Field_1_0'],
            [['Level Life Cover', 'Family Income Benefit', 'Whole of Life Cover'],
            'Field_1 policy type'],
            [['Sum assured', 'Benefit amount'], 'Field_2'],
            [['£ii_Field_52_1', '£ii_Field_53_2 a month'], 'Field_3'],
            [['ii_Field_62_1 years', 'to age ii_Field_63_2', 'Whole of life'], 'Field_4'],
             .....]

dl 列表的长度未知 n,但每个元素 dl[i] 中嵌套了 2 个列表,第一个 (dl[i][0]) 可能替换第二个元素 (dl[i][1])。

k_all_tbl 看起来像这样:

k_all_tbl =[[[[['Name']], [['INSERT_3']]],
            [[['Product']], [['S_Field_1_0'], [' '], ['Field_1 policy type']]],
            [[['Field_2']], [['Field_3']]],

           [[[['Name']], [['INSERT_9']]],
            [[['Product']],
             [['INSERT_10'], [' '], ['S_Field_19_18'], [' '], ['INSERT_11']]],
            [[['Sum assured']], [['£'], ['INSERT_12']]],
             .....]

k_all_tbl(从表数据中提取)也有未知长度m,但每个元素k_all_tbll[j](每一行)有2个嵌套在其中的列表,有(k_all_tbll[j][0])和(k_all_tbll[j][1])(column1和原始表的第 2 列)正在链接。

要求的简短版本是我需要创建以下输出:

k_all_tbl[0] =[[['Name'], ['INSERT_3']],
                [[['Product']], [['Aegon', ' ', 'Level Life Cover'],
                  ['Aegon', ' ', 'Family Income Benefit'],
                  ['Aegon', ' ', 'Whole of Life Cover'],
                  ['Aviva', ' ', 'Level Life Cover'],
                  ['Aviva', ' ', 'Family Income Benefit'],
                  ['Aviva', ' ', 'Whole of Life Cover'],
                  ['HSBC', ' ', 'Level Life Cover'],
                  ['HSBC', ' ', 'Family Income Benefit'],
                  ['HSBC', ' ', 'Whole of Life Cover'],
                  ['Zurich', ' ', 'Level Life Cover'],
                  ['Zurich', ' ', 'Family Income Benefit'],
                  ['Zurich', ' ', 'Whole of Life Cover']]],

                [[['Sum assured', '£ii_Field_52_1'],
                  ['Sum assured', '£ii_Field_53_2 a month'],
                  ['Benefit amount', '£ii_Field_52_1'],
                  ['Benefit amount', '£ii_Field_53_2 a month']]]

但是我在下面详细分享的代码和步骤并没有让我在这里,它在没有执行的情况下崩溃,或者给了我错误的排列。任何和所有的帮助将不胜感激。详细解释和代码尝试如下。

尝试的方法:

我首先尝试:对于k_all_tbl[j][0][k] 中与元素dl[i][1] 对应的每个元素,将k_all_tbl[j][0][k] 替换为(dl[i][0])。输出示例为:

k_all_tbl[0] =[[[[['Name']], [['INSERT_3']]],
            [[['Product']], [[['Aegon', 'Aviva', 'HSBC', 'Zurich']], [' '], [['Level Life Cover', 'Family Income Benefit', 'Whole of Life Cover']]]],
            [[[['Sum assured', 'Benefit amount']]], [[['£ii_Field_52_1', '£ii_Field_53_2 a month']]]]

我通过运行以下代码实现了上述目标:

for ik in range(0,len(k_all_tbl)):
    k_all_tbl[ik] = unlevel(k_all_tbl[ik])
    for ikk in range(0,len(k_all_tbl[ik])):

            for ikkk in range(0,(len (k_all_tbl[ik][ikk]))):

                    for res1 in dropdown_result:
                        if isinstance(k_all_tbl[ik][ikk][ikkk], list)==False: 

                            if  k_all_tbl[ik][ikk][ikkk] == res1[1]:
                                k_all_tbl[ik][ikk][ikkk] = res1[0]


                        if len(k_all_tbl[ik][ikk][ikkk]) >1:
                            for ikkkk in range(0,(len (k_all_tbl[ik][ikk][ikkk]))):
                                if  k_all_tbl[ik][ikk][ikkk][ikkkk] == res1[1]:
                                    k_all_tbl[ik][ikk][ikkk][ikkkk] = res1 [0]

其中函数unlevel用于访问单个元素嵌套列表中的项目,即unlevel([[[[["target"]],1]]]) = '[[target],1]',定义为:

def unlevel(obj):
    while isinstance(obj, list) and len(obj) == 1:
        obj = obj[0]
    if isinstance(obj, list):
        return [unlevel(item) for item in obj]
    else:
        return obj

然后我需要删除不必要的括号,并为k_all_tbl 中的每个元素创建“产品”,例如k_all_tbl[0]

k_all_tbl[0] =[[['Name'], ['INSERT_3']],
                [[['Product']], [['Aegon', ' ', 'Level Life Cover'],
                  ['Aegon', ' ', 'Family Income Benefit'],
                  ['Aegon', ' ', 'Whole of Life Cover'],
                  ['Aviva', ' ', 'Level Life Cover'],
                  ['Aviva', ' ', 'Family Income Benefit'],
                  ['Aviva', ' ', 'Whole of Life Cover'],
                  ['HSBC', ' ', 'Level Life Cover'],
                  ['HSBC', ' ', 'Family Income Benefit'],
                  ['HSBC', ' ', 'Whole of Life Cover'],
                  ['Zurich', ' ', 'Level Life Cover'],
                  ['Zurich', ' ', 'Family Income Benefit'],
                  ['Zurich', ' ', 'Whole of Life Cover']]],

                [[['Sum assured', '£ii_Field_52_1'],
                  ['Sum assured', '£ii_Field_53_2 a month'],
                  ['Benefit amount', '£ii_Field_52_1'],
                  ['Benefit amount', '£ii_Field_53_2 a month']]]

我在上面代码的底部尝试了以下两个函数来尝试实现这一点:

for ik in range(0,len(k_all_tbl)):
        #loop through lists inside nested list -if single element list is nested, remove list before comparison, if more than 1 element keep list, and iterativley compare
        for ikk in range(0,len(k_all_tbl[ik])):

            for ikkk in range(0,(len (k_all_tbl[ik][ikk]))):

                    for res1 in dl:
                        if isinstance(k_all_tbl[ik][ikk][ikkk],list)==True and len(k_all_tbl[ik][ikk][ikkk])==1:
                            k_all_tbl[ik][ikk][ikkk] = unlevel(k_all_tbl[ik][ikk][ikkk])
                            if  k_all_tbl[ik][ikk][ikkk] == res1[1]:
                                k_all_tbl[ik][ikk][ikkk] = res1[0]
                             k_all_tbl[ik][ikk][ikkk] = unlistme(k_all_tbl[ik][ikk][ikkk])
                             k_all_tbl[ik][ikk] = spreadm(k_all_tbl[ik][ikk])


                        if len(k_all_tbl[ik][ikk][ikkk]) >1:
                            for ikkkk in range(0,(len (k_all_tbl[ik][ikk][ikkk]))):
                                if  k_all_tbl[ik][ikk][ikkk][ikkkk] == res1[1]:
                                    k_all_tbl[ik][ikk][ikkk][ikkkk] = res1 [0]
                            k_all_tbl[ik][ikk][ikkk] = unlistme(k_all_tbl[ik][ikk][ikkk])
                            k_all_tbl[ik][ikk] = spreadm(k_all_tbl[ik][ikk])
##function to create permutations
def product(llist):
    result = [[]]
    for lst in llist:
        result = [x + [y] for x in result for y in lst]
    return result


#Function to put single string elements in lists, i.e. "Target" must be changed to ["Target"], otherise the loop will iterate accross "T"-"A"-"R"-"G"-"E"-"T" characters:
def unlistme(ktest):
        ktest2 = []
        for ktt in ktest:
            kttls=[]
            if isinstance(ktt,list)==True:
                ktest2.append(ktt)
            if isinstance(ktt,list)==False:
                kttls.append(ktt)
                ktest2.append(kttls)
        return(ktest2)


#function to open nested list into sublist using product
def spreadm(kx2):
    if isinstance(kx2,list) ==True:
    
        out = product(kx2)
    else:
            out = kx2
    return(out)

【问题讨论】:

  • 阅读this article 了解调试代码的技巧。
  • @Code-Apprentice 非常感谢会阅读文档,我可能希望手动执行此操作的方式更少循环、混乱,我可能错过了一个功能或在 itertools 中映射...
  • 粗略一瞥,您可能会受益于学习pandas。这是一个 Python 库,通常用于存储和操作数据表。

标签: python list nested permutation


【解决方案1】:

所以为了解决这个问题,我使用了以下两个循环,其功能与上面在 OP 中定义的功能相同。第一个循环使用参考数据帧 dl 中的相应字段进行替换,而第二个循环搜索第三级嵌套,如果至少存在一个列表,则尝试创建排列:

for ik in range(0,len(k_all_tbl)):
    k_all_tbl[ik] = unlevel(k_all_tbl[ik])
    for ikk in range(0,len(k_all_tbl[ik])):

            for ikkk in range(0,(len (k_all_tbl[ik][ikk]))):

                    for res1 in dl:
                        if isinstance(k_all_tbl[ik][ikk][ikkk], list)==False: 

                            if  k_all_tbl[ik][ikk][ikkk] == res1[1]:
                                k_all_tbl[ik][ikk][ikkk] = res1[0]


                        if len(k_all_tbl[ik][ikk][ikkk]) >1:
                            for ikkkk in range(0,(len (k_all_tbl[ik][ikk][ikkk]))):
                                if  k_all_tbl[ik][ikk][ikkk][ikkkk] == res1[1]:
                                    k_all_tbl[ik][ikk][ikkk][ikkkk] = res1 [0]



for kj in range(0,len(k_all_tbl)):
    for kj1 in range(0,len(k_all_tbl[kj])):
        for kz in range(0,len(k_all_tbl[kj][kj1])):
            
            if any(isinstance(i, list) for i in k_all_tbl[kj][kj1][kz])==True: #and any(isinstance(i, str) for i in k_all_tbl[kj][kj1])==True:
                k_all_tbl[kj][kj1][kz] = spreadm(unlistme(k_all_tbl[kj][kj1][kz]))

输出:

[[['Name', 'INSERT_3'],
  ['Product',
   [['Aegon', ' ', 'Level Life Cover'],
    ['Aegon', ' ', 'Family Income Benefit'],
    ['Aegon', ' ', 'Whole of Life Cover'],
    ['Aviva', ' ', 'Level Life Cover'],
    ['Aviva', ' ', 'Family Income Benefit'],
    ['Aviva', ' ', 'Whole of Life Cover'],
    ['HSBC', ' ', 'Level Life Cover'],
    ['HSBC', ' ', 'Family Income Benefit'],
    ['HSBC', ' ', 'Whole of Life Cover'],
    ['Zurich', ' ', 'Level Life Cover'],
    ['Zurich', ' ', 'Family Income Benefit'],
    ['Zurich', ' ', 'Whole of Life Cover']]],
  [['Sum assured', 'Benefit amount'],
   ['£ii_Field_52_1', '£ii_Field_53_2 a month']],
  ['Term', ['ii_Field_62_1 years', 'to age ii_Field_63_2', 'Whole of life']],
  ['Premium', ['£', 'INSERT_4', ' a month']],
  ['Payable on', ['Death', 'First death']],
  ['Trust recommended', ['Yes', 'No']]],
 [['Name', 'INSERT_9'],
   .....]

【讨论】:

    猜你喜欢
    • 2019-08-30
    • 1970-01-01
    • 2019-12-14
    • 1970-01-01
    • 1970-01-01
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    • 2017-07-29
    相关资源
    最近更新 更多