【问题标题】:Comparing a list and dictionary and print it to YML file比较列表和字典并将其打印到 YML 文件
【发布时间】:2019-03-28 16:51:35
【问题描述】:

我有列表和字典,现在我需要将字典中的键与列表中的键进行比较,并将匹配结果打印到 YML 文件中。 所以这是我的字典键,

samples1.keys()
dict_keys(['C3N-02289_10_L1', 'C3N-02289_10_L2', 'C3N-02671_08_L1', 'C3N-02671_08_L2','C3N-02671_10_L1','C3N-02671_10_L1' ])

我有 2 个列表,

Left_reads = [
    'C3N-02289_10_L1_R1.gz',
    'C3N-02289_10_L2_R1.gz',
    'C3N-02671_08_L1_R1.gz',
    'C3N-02671_08_L2_R1.gz',
    'C3N-02671_10_L1_R1.gz',
    'C3N-02671_10_L2_R1.gz'
 ]



 Right_reads = [
    'C3N-02289_10_L1_R2.gz',
    'C3N-02289_10_L2_R2.gz',
    'C3N-02671_08_L1_R2.gz',
    'C3N-02671_08_L2_R2.gz',
    'C3N-02671_10_L1_R2.gz',
    'C3N-02671_10_L2_R2.gz'
]

现在我需要将字典 (samples1.key) 中的每个键与列表中的值 (Left_readsRight_reads) 进行比较。如果密钥与列表中的字符串匹配,则将其打印到 YML 文件。 这是我尝试过的,

for sam in samples1.keys():
    ymlFile = pat + sam + '.yml'
    ymlFH = open(ymlFile, 'w')

    ymlFH.write("reads1: [\n")
    for sam in sorted(Left_reads):
        ymlFH.write(" {class: File, path: " + path + '/' + sam + "}, \n")
    ymlFH.write("]\n")

    ymlFH.write("reads2: [\n")    
    for sam in sorted(Right_reads):
        ymlFH.write(" {class: File, path: " + path + '/' + sam + "}, \n")
    ymlFH.write("]\n")
    ymlFH.close()

这会将列表Left_readsRight_reads 中的所有值打印到reads1reads2

我的目标是有一个输出来打印列表中的每个值,例如,对于文件C3N-02289_10_L1.yml,输出应该是这样的,所以这里我的所有值都与C3N-02289_10_L1和C@987654333匹配@。我需要脚本来比较前缀,也就是C3N-02289_10在列表和字典之间然后写入YML文件

reads1: [
 {class: File, path: /usr/path/C3N-02289_10_L1_R1.gz}, 
 {class: File, path: /usr/path/C3N-02289_10_L2_R1.gz},

]
reads2: [
 {class: File, path: /usr/path/C3N-02289_10_L1_R2.gz}, 
 {class: File, path: /usr/path/C3N-02289_10_L2_R2.gz},

]

字典中的所有值、列表中的匹配字符串等都是相同的。 使用我上面的一段代码,C3N-02289_10_L1.yml 的输出看起来像,

 reads1: [
     {class: File, path: /usr/path/C3N-02289_10_L1_R1.gz}, 
     {class: File, path: /usr/path/C3N-02289_10_L2_R1.gz},
    {class: File, path: /usr/path/C3N-02671_08_L1_R1.gz}, 
    {class: File, path: /usr/path/C3N-02671_08_L2_R.gz},
    {class: File, path: /usr/path/C3N-02671_10_L1_R1.gz},
    {class: File, path: /usr/path/C3N-02671_10_L2_R1.gz} , 
    ]
    reads2: [
     {class: File, path: /usr/path/C3N-02289_10_L1_R2.gz}, 
     {class: File, path: /usr/path/C3N-02289_10_L2_R2.gz},
    {class: File, path: /usr/path/C3N-02671_08_L1_R2.gz}, 
    {class: File, path: /usr/path/C3N-02671_08_L2_R2.gz},
    {class: File, path: /usr/path/C3N-02671_10_L1_R2.gz},
    {class: File, path: /usr/path/C3N-02671_10_L2_R2.gz} 
    ]

【问题讨论】:

  • 什么是 YML 文件?有一种叫做 YAML 的东西,如果可能的话,你应该使用 .yaml 文件扩展名 (yaml.org/faq.html)。如果您想编写那种文件,请始终使用像 ruamel.yamlPyYAML 这样的 YAML 库(以防您只需要支持过时的 YAML 1.1 规范)。

标签: python-3.x list dictionary yaml


【解决方案1】:

首先让我们从你的目标开始。

在您的代码中,字典中的键与列表中的值之间没有比较。据我了解,您想检查当前字典键是否是列表中值的前缀,如果是,则将该文件名转储到 .yaml 文件。

所以你的代码应该是这样的:

for prefix in samples1.keys():
    for filename in some_list:
        if filename.startswith(prefix):
            # add the {class: File, path: some/path/filename } to the yaml file

您的代码的第二个输出不是有效的 yaml 文件。 我推荐使用PyYaml 包。

如果我们把它们放在一起,我们会得到:

import yaml

# definition of path variable is here somewhere...

# edited to take only the prefixes of the keys
desired_keys = ['_'.join(k.split('_')[:-1]) for k in samples1.keys()]

for prefix in desired_keys:
    yml_filename = prefix + '.yaml'
    reads1 = []
    for filename in Left_reads:
        if filename.startswith(prefix):
            reads1.append({'class': 'File', 'path': path + '/' + filename})

    reads2 = []
    for filename in Right_reads:
        if filename.startswith(prefix):
            reads2.append({'class': 'File', 'path': path + '/' + filename})

    data = {'reads1': reads1, 'reads2': reads2 }
    stream = open(yml_filename, 'w')
    yaml.dump(data, stream)
    stream.close()

顺便说一句,我建议使用os.path.join(path, filename) 方法而不是path + '/' + filename,以减少出错的可能性。

编辑

使用给定的Left_readsRight_readssamples1.keys(),结果是三个.yml 文件:

C3N-02289_10.yml C3N-02671_08.yml C3N-02671_10.yml

第一个,即C3N-02289_10.yml 包含:

reads1:
- {class: File, path: /path/yamlTest/__main__/C3N-02289_10_L1_R1.gz}
- {class: File, path: /path/yamlTest/__main__/C3N-02289_10_L2_R1.gz}
reads2:
- {class: File, path: /path/yamlTest/__main__/C3N-02289_10_L1_R2.gz}
- {class: File, path: /path/yamlTest/__main__/C3N-02289_10_L2_R2.gz}

【讨论】:

  • 这是抛出错误,TypeError Traceback (最近一次调用最后一次) in 13 14 data = {'reads1': reads1, 'reads2': reads2 } ---> 15 stream = file(yml_filename, 'w') 16 yaml.dump(data, stream) TypeError: 'str' object is not callable。前缀的更多内容是与整个列表进行比较并返回列表中的所有内容。
  • 我没有收到任何错误。你在运行 python 2.7 吗?
  • 我正在尝试使用 python 3
  • 新的编辑仍然存在错误:TypeError Traceback (最近一次调用最后) in 19 20 data = {'reads1': reads1, ' reads2': reads2 } ---> 21 stream = file(yml_filename, 'w') 22 yaml.dump(data, stream) 23 TypeError: 'str' object is not callable
  • 在我的情况下,输出 yml 文件不会像您看到的那样显示行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-03
  • 1970-01-01
  • 2015-01-25
  • 2021-04-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多