首页 > 解决方案 > 每个键将几乎相同的字典值列表组合在一起

问题描述

我有一个这样的输入文件:

structureId chainId resolution  uniprotAcc  structureMolecularWeight
101M    A   2.07    P02185  18112.8
102L    A   1.74    P00720  18926.61
103D    A                   7502.93
103D    B                   7502.93
103L    A   1.9     P00720  19092.72
103M    A   2.07    P02185  18093.78
104L    A   2.8     P00720  37541.04
104L    B   2.8     P00720  37541.04
104M    A   1.71    P02185  18030.63
104M    A   3.1     P09323  2312.2

我希望输出看起来像这样:

structureId chainId resolution  uniprotAcc  structureMolecularWeight

101M    A   2.07    P02185  18112.8
102L    A   1.74    P00720  18926.61
103D    A                   7502.93
103D    B                   7502.93
103L    A   1.9     P00720  19092.72
103M    A   2.07    P02185  18093.78
104L    A,B 2.8     P00720  37541.04
104M    A   1.71    P02185  18030.63
104M    A   3.1     P09323  2312.2

即如果 col 'uniprotAcc' 与 col 'structureId' 相同;将它们结合起来。

我写了这段代码:

import sys

set_of_ids = list(set([line.strip().split('\t')[0] for line in open(sys.argv[1])]))

master_dict = {}
for line in open(sys.argv[1]):
    split_line = line.strip().split('\t')
    if split_line[0] not in master_dict:
        master_dict[split_line[0]] = [split_line[1:]]
    else:
        master_dict[split_line[0]].append(split_line[1:])

print(master_dict)

它结合了数据,因此键是结构 ID,值是结构 ID 所涉及的行列表:

{'structureId': [['chainId', 'resolution', 'uniprotAcc', 'structureMolecularWeight']], '101M': [['A', '2.07', 'P02185', '18112.8']], '102L': [['A', '1.74', 'P00720', '18926.61']], '103D': [['A', '', '', '7502.93'], ['B', '', '', '7502.93']], '103L': [['A', '1.9', 'P00720', '19092.72']], '103M': [['A', '2.07', 'P02185', '18093.78']], '104L': [['A', '2.8', 'P00720', '37541.04'], ['B', '2.8', 'P00720', '37541.04']], '104M': [['A', '1.71', 'P02185', '18030.63'], ['A', '3.1', 'P09323', '2312.2']]}

我只是坚持一件小事,我知道如何遍历字典:

for k in master_dict:
    for each_list in master_dict[k]:

我只是停留在下一行,怎么说'合并除了第一个(假设列表从 0 开始)项之外相同的列表。

即转:

104L    A   2.8     P00720  37541.04
104L    B   2.8     P00720  37541.04

进入:

104L    A,B   2.8     P00720  37541.04

基本上,对于我的表中的行,我可能使它听起来比实际更复杂,如果每个结构 ID 和每个 uniProtacc 的唯一区别是chainID 列,则组合chainID 列。

编辑1:下面的答案有问题吗?

例如,这是数据:

structureId chainId resolution  uniprotAcc  structureMolecularWeight
6YC3    A   2.0 N0DKS8  181807.39
6YC3    B   2.0 N0DKS8  181807.39
6YC3    C   2.0 N0DKS8  181807.39
6YC3    D   2.0 N0DKS8  181807.39
6YC3    E   2.0 N0DKS8  181807.39
6YC4    A   2.6 N0DKS8  174142.86
6YC4    B   2.6 N0DKS8  174142.86
6YC4    C   2.6 N0DKS8  174142.86
6YC4    D   2.6 N0DKS8  174142.86
6YC4    E   2.6 N0DKS8  174142.86

那么输出应该是:

6YC3 A,B,C,D,E 2.0 N0DKS8 181807.29
6YC4 A,B,C,D,E 2.6 N0DKS8 174142.86

而下面代码的输出是:

['6YC3', 'B,B,C,D,E,A,B,C,D,E', '2.0', 'N0DKS8', '181807.39']

编辑 2:为避免上述问题,我创建了一个结合 UniProt 加入和结构 ID 的列:

structureId chainId resolution  uniprotAcc  structureMolecularWeight    newcode
6YC3    A   2.0 N0DKS8  181807.39   N0DKS8_6YC3
6YC3    B   2.0 N0DKS8  181807.39   N0DKS8_6YC3
6YC3    C   2.0 N0DKS8  181807.39   N0DKS8_6YC3
6YC3    D   2.0 N0DKS8  181807.39   N0DKS8_6YC3
6YC3    E   2.0 N0DKS8  181807.39   N0DKS8_6YC3
6YC4    A   2.6 N0DKS8  174142.86   N0DKS8_6YC4
6YC4    B   2.6 N0DKS8  174142.86   N0DKS8_6YC4
6YC4    C   2.6 N0DKS8  174142.86   N0DKS8_6YC4
6YC4    D   2.6 N0DKS8  174142.86   N0DKS8_6YC4
6YC4    E   2.6 N0DKS8  174142.86   N0DKS8_6YC4

然后我只是替换了代码中的行:

idx_uniprotAcc = headers.index("uniprotAcc") #to...
idx_uniprotAcc = headers.index("newcode")

当我运行与下面完全相同的代码时,只更改了一行,输出为:

['6YC3', 'B,B,C,D,E', '2.0', 'N0DKS8', '181807.39', 'N0DKS8_6YC3']
['6YC4', 'A,B,C,D,E', '2.6', 'N0DKS8', '174142.86', 'N0DKS8_6YC4']

为什么第一行返回'B,B,C,D,E'而不是'A,B,C,D,E'。我认为这与迭代数据[1:]有关吗?

标签: pythonjson

解决方案


您可以使用zipinbuilt 执行逐项连接。map可用于进一步处理。

对于给定的输入 -

item = [['A', '2.8', 'P00720', '37541.04'], ['B', '2.8', 'P00720', '37541.04']]

output=list(map(lambda t: t[0] if t[0]==t[1] else t[0]+","+t[1], list(zip(*a))))

结果是——

['A,B', '2.8', 'P00720', '37541.04']

注意: 中的 lambdamap假设最多 2 行被污染。您也可以轻松地将其更改为 n 。


推荐阅读