Python:替换子列表的值,从另一个子列表中查找值而不编制索引

时间:2016-12-09 16:49:45

标签: python list python-3.x replace

描述

我有两个从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. 

正如您所看到的,这个解决方案显然效率低下,我无法找到最好的方法来执行最后几步。

如果不清楚,我可以添加更多信息

2 个答案:

答案 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])