我有两个从CSV派生的列表列表(下面的最小工作示例)。这个真正的数据集太大,无法手动执行此操作。
mainlist = [["MH75","QF12",0,38], ["JQ59","QR21",105,191], ["JQ61","SQ48",186,284], ["SQ84","QF36",0,123], ["GA55","VA63",80,245], ["MH98","CX12",171,263]]
replacelist = [["MH75","QF12","BA89","QR29"], ["QR21","JQ59","VA51","MH52"], ["GA55","VA63","MH19","CX84"], ["SQ84","QF36","SQ08","JQ65"], ["SQ48","JQ61","QF87","QF63"], ["MH98","CX12","GA34","GA60"]]
mainlist
包含一对标识符(mainlist[x][0]
,mainlist[x][1]
),这些标识符与两个整数相关联(mainlist[x][2]
和mainlist[x][3]
)
replacelist
是第二个列表列表,它们也包含相同的标识符对(但在一对或跨行的顺序不同)。所有子列表对都是唯一的。 重要的是, replacelist[x][2],replacelist[x][3]
分别对应replacelist[x][0],replacelist[x][1]
的替换。
我需要创建一个新的第三个列表,newlist
复制mainlist
,但将标识符替换为replacelist[x][2],replacelist[x][3]
例如,给定:
mainlist[2]
是:[JQ61,SQ48,186,284]
重传者中的匹配对为
replacelist[4]: [SQ48,JQ61,QF87,QF63]
因此预期的产出是
newlist[2] = [QF87,QF63,186,284]
更清楚地说: if replacelist = [[A,B,C,D]] A替换为C,B替换为D. 但它可能在主列表中显示为[[B,A]]
注意新列表行位置使用与主列表相同的
我对一个简单的问题感到困惑的是,我觉得我不能使用基本列表理解[i for i in replacelist if i in mainlist]
,因为一对中的顺序发生了变化,如果我sorted(list)
那么我就失去了关于什么的信息用。替换列表。当前解决方案(带注释空白):
newlist = []
for k in replacelist:
for i in mainlist:
if k[0] and k[1] in i:
# retrieve mainlist order, then use some kind of indexing to check a series of nested if statements to work out positional replacement.
正如您所看到的,这个解决方案显然效率低下,我无法找到最好的方法来执行最后几步。
如果不清楚,我可以添加更多信息
答案 0 :(得分:1)
你做的第一件事 - 转换字典中的两个列表:
from collections import OrderedDict
maindct = OrderedDict((frozenset(item[:2]),item[2:]) for item in mainlist)
replacedct = {frozenset(item[:2]):item[2:] for item in replacementlist}
# Now it is trivial to create another dict with the desired output:
output_list = [replacedct[key] + maindct[key] for key in maindct]
这里最重要的是通过使用字典,您取消了替换列表上索引的搜索时间 - 在列表中您必须扫描每个项目的所有列表,这会使您的性能更糟列表长度的平方。使用Python词典,搜索时间是恒定的 - 并且根本不依赖于数据长度。
答案 1 :(得分:1)
如果您将replacelist
作为词典,那将会有所帮助:
mainlist = [[MH75,QF12,0,38], [JQ59,QR21,105,191], [JQ61,SQ48,186,284], [SQ84,QF36,0,123], [GA55,VA63,80,245], [MH98,CX12,171,263]]
replacelist = [[MH75,QF12,BA89,QR29], [QR21,JQ59,VA51,MH52], [GA55,VA63,MH19,CX84], [SQ84,QF36,SQ08,JQ65], [SQ48,JQ61,QF87,QF63], [MH98,CX12,GA34,GA60]]
replacements = {frozenset(r[:2]):dict(zip(r[:2], r[2:])) for r in replacements}
newlist = []
for *ids, val1, val2 in mainlist:
reps = replacements[frozenset([id1, id2])]
newlist.append([reps[ids[0]], reps[ids[1]], val1, val2])