Python 创建不规则嵌套循环的产品置换
对于冗长的解释,我深表歉意,我有两个嵌套列表,一个包含一系列字段的引用值,称为Python 创建不规则嵌套循环的产品置换,python,list,nested,permutation,Python,List,Nested,Permutation,对于冗长的解释,我深表歉意,我有两个嵌套列表,一个包含一系列字段的引用值,称为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
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]
中嵌套有两个列表,第一个(dl[i][0]
)可能替换第二个元素(dl[i][1]
)
k\u all\u 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]
)(原始表的第1列和第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)
为了解决这个问题,我使用了以下两个循环,函数与上面在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'],
.....]
阅读有关调试代码的提示。@code学徒非常感谢您阅读文档,我可能希望有一种不那么复杂、混乱的手动方式,我可能错过了一个函数或在itertools中映射…粗略地看一下,您可能会从学习
pandas
中受益。这是一个Python库,通常用于存储和操作数据表。