将文件中多行的记录读入python中的嵌套字典

2024-10-01 05:03:53 发布

您现在位置:Python中文网/ 问答频道 /正文

这是练习嵌套字典,或字典数组,字典列表等。 在C/C++中,数据结构可以最好地描述为结构/类的数组,每个结构都有多个成员。对我的挑战:
1). 在每条记录的开头有字符串“示例名称”作为分隔符,后跟多个成员;
2). 每行6个记录成员,用冒号分隔“;
3). 如何将多行(而不是同一行的多个字段,这更容易解析)读入记录的成员中;
4). 记录分隔符前面不能有空行。
我将样本输入和预期输出放入测试中。
示例:输入文件


Sample Name: CanNAM1_192
SNPs                         : 5392
MNPs                         : 0
Insertions                   : 248
Deletions                    : 359
Phased Genotypes             : 8.8% (2349/26565)
MNP Het/Hom ratio            : - (0/0)

Sample Name: CanNAM2_195
SNPs                         : 5107
MNPs                         : 0
Insertions                   : 224
Deletions                    : 351
Phased Genotypes             : 8.9% (2375/26560)
MNP Het/Hom ratio            : - (0/0)

Sample Name: CanNAM3_196
SNPs                         : 4926
MNPs                         : 0
Insertions                   : 202
Deletions                    : 332
Phased Genotypes             : 8.0% (2138/26582)
MNP Het/Hom ratio            : - (0/0)

在awk中,有记录分隔符RS和字段分隔符FS可以在开始时设置,但据我所知,python中没有这样的函数。你知道吗

输出.tab:

CanNAM1_192  5392  0  248  359  8.8%  - 
CanNAM2_195  5107  0  224  351  8.9%  - 
CanNAM3_196  4926  0  202  332  8.0%  - 

尝试搜索一些示例代码来查找我的案例,例如onethis one

import sys

filename=sys.argv[1]

Dictn = {}

with open(filename, 'r') as fh:
    for line in fh:
        while True:
            if line.startswith('Sample Name'):
                nameLine = line.strip()
                ID = nameLine.split(':')
            else:
                line2 = next(fh).strip()
                line2 = line2.split(':')
                print (line2[0], line2[1]) # For debugging to see the parsing result
                line3 = next(fh).strip().split(':')
                line4 = next(fh).strip().split(':')
                line5 = next(fh).strip().split(':')
                line6 = next(fh).strip().split(':')
                line7 = next(fh).strip().split(':')
                Dictn.update({
                            ID[1]: {
                                line2[0]: line2[1],
                                line3[0]: line3[1],
                                line4[0]: line4[1],
                                line5[0]: line5[1],
                                line6[0]: line6[1],
                                line7[0]: line7[1],
                                }
                             })
                break
print(Dictn)

Dictn.get('CanNAM1_192')
# {CanNAM1_192:{ {'SNPs' : '5392'}, {'MNPs' : '0'}, {'Insertions' : '248'}, {'Deletions' : '359'}, {'Phased Genotypes' : '8.8%'}, {'MNP Het/Hom ratio' : '-'} }}

我一直在解析每条记录,每次读7行,然后将记录推入/更新到字典中。不擅长Python,我真的很感谢任何帮助!你知道吗


Tags: samplename字典记录成员nextsplitstrip
2条回答
data = {}
with open("data.txt",'r') as fh:
    for line in fh.readlines(): #read in multiple lines
        if len(line.strip())==0:
            continue

        if line.startswith('Sample Name'):
            nameLine = line.strip()
            name = nameLine.split(": ")[1]
            data[name] = {}
        else:
            splitLine = line.split(":")
            variableName = splitLine[0].strip()
            value = splitLine[1].strip()
            data[name][variableName] = value

print(data)
  1. 确保你正在读的那行不是空的。如果将空行中的所有空格去掉,将得到一个长度为零的字符串。我们只是检查一下。你知道吗
  2. 如果该行以Sample Name开头,我们知道id将位于冒号和空格之后。我们可以用这些字符来划分。id将是分割行的第二部分,因此我们只得到索引1处的项。你知道吗
  3. 在变量中跟踪当前id(我称之为name)。为该id创建一个空的嵌套字典条目
  4. 如果该行不是ID行,则它必须是与上次输入的ID关联的数据行
  5. 我们得到这条线,把它除以:。变量的名称在左边,第一项在右边,值在右边,所以第二项在右边。一定要把两边多余的空间都去掉。你知道吗
  6. 将变量和值对添加到ID的字典条目中

在这个问题上花了更多的时间,得到了一个解决方案,它看起来是“强>不<强”>“Python”,因为我的代码处理第一个“记录”(8行数据,包括底部的空白行)是其余的冗余。你知道吗

import itertools
data = {}
with open("vcfstats.txt", 'r') as f:
    for line in f:
        if line.strip():                #Non blank line
            if line.startswith('Sample Name'):
                nameLine = line.strip()
                name = nameLine.split(": ")[1].strip()
                data[name] = {}
            else:
                splitLine = line.split(": ")
                variableName = splitLine[0].strip()
                values = splitLine[1].strip().split(" ")
                data[name][variableName] = values[0]        #Only take the first item as value
        else:
             continue

    for line in itertools.islice(f, 8):
        lines = (line.rstrip() for line in f)          # including blank lines
        lines = list(line for line in lines if line)   # skip blank lines

        for line in lines:
            if line.startswith('Sample Name'):
                nameLine = line.strip()
                name = nameLine.split(": ")[1].strip()
                data[name] = {}
            else:
                splitLine = line.split(": ")
                variableName = splitLine[0].strip()
                values = splitLine[1].strip().split(" ")
                data[name][variableName] = values[0]        #Only take the first item as value

我错过了什么?谢谢!你知道吗

相关问题 更多 >