2017-10-28 142 views
0

我想创建一个JSON对象并将其附加到列表中,但没有成功。 我得到这个错误按摩:在python中创建一个JSON对象

Traceback (most recent call last): 
    File "/projects/circos/test.py", line 32, in <module> 
    read_relationship('data/chr03_small_n10.blast') 
    File "/projects/circos/test.py", line 20, in read_relationship 
    tmp = ("[source: {id: '{}',start: {},end: {}},target: {id: '{}',start: {}, end: {}}],").format(parts[0],parts[2],parts[3],parts[1],parts[4],parts[5]) 
KeyError: 'id' 

用下面的代码

def read_relationship(filename): 
    data = [] 
    with open(filename) as f: 
     f.next() 
     for line in f: 
      try: 
       parts = line.rstrip().split('\t') 
       query_name = parts[0] 
       subject_name = parts[1] 
       query_start = parts[2] 
       query_end = parts[3] 
       subject_start = parts[4] 
       subject_end = parts[5] 


       # I need: [source: {id: 'Locus_1', start: 1, end: 1054}, target: {id: 'tig00007234', start: 140511, end: 137383}], 
       tmp = ("[source: {id: '{}',start: {},end: {}},target: {id: '{}',start: {}, end: {}}],").format(parts[0],parts[2],parts[3],parts[1],parts[4],parts[5]) 
       data.append(tmp) 

      except ValueError: 
       pass 

    with open('data/data.txt', 'w') as outfile: 
     json.dump(data, outfile) 


read_relationship('data/chr03_small_n10.blast') 

我错过了什么?

+2

是不是应该是JSON文件的一部分?因为它会被转储为不透明的字符串值。并不是说它可以被视为有效的JSON。 –

回答

2

您正在使用json.dump()函数错误。

你传递一个对象和文件对象:对键值映射

json.dump(object, fileobject) 

使用字典:

def read_relationship(filename): 
    data = [] 
    with open(filename) as f: 
     f.next() 
     for line in f: 
      try: 
       parts = line.rstrip().split('\t') 
       query_name = parts[0] 
       subject_name = parts[1] 
       query_start = parts[2] 
       query_end = parts[3] 
       subject_start = parts[4] 
       subject_end = parts[5] 

       # use dict here 
       item = { 
        'source': { 
         'id': query_name, 
         'start': subject_name, 
         'end': query_start 
       }, 
        'target': { 
         'id': query_end, 
         'start': subject_start, 
         'end': subject_end 
        } 
       } 
       data.append(item) 

      except ValueError: 
       pass 

    with open('data/data.txt', 'w') as outfile: 
     json.dump(data, outfile) 


read_relationship('data/chr03_small_n10.blast') 
+0

而不是'[{“source”:{“'是否有可能获得'[[”source“:{”'因为我需要这个https://github.com/nicgirault/circosJS#chords? – user977828

+0

您不能将一个键值对放入列表/数组中。这将是一个无效的JSON字符串。请自行停止格式化JSON字符串。 –

+0

你是对的,怎么可能在一个新行中写每个列表元素? – user977828

1

您需要double{}不是占位符的字符; {id:...}被视为以其他方式命名占位符:

tmp = (
    "[source: {{id: '{}',start: {},end: {}}}," 
    "target: {{id: '{}',start: {}, end: {}}}],").format(
     parts[0], parts[2], parts[3], parts[1], parts[4], parts[5]) 

{{}}序列结束在结果单{}字符。

而不是把你所有的部件在单独,使用编号插槽:

tmp = (
    "[source: {{id: '{0}',start: {2},end: {3}}}," 
    "target: {{id: '{1}',start: {4}, end: {5}}}],").format(
     *parts) 

你应该考虑使用csv模块读取您的TSV的数据,如果你的意思是针对上述数据是部分JSON文档(不是嵌入字符串,而是单独的JSON数组和对象),然后将其格式化为字符串将不起作用。

您需要将您的CSV列的第一转换为整数,但:

import csv 
import json 

def read_relationship(filename): 
    data = [] 
    with open(filename, 'rb') as f: 
     reader = csv.reader(f, delimiter='\t') 
     next(reader, None) 
     for row in reader: 
      data.append([{ 
       'source': { 
        'id': row[0], 
        'start': int(row[2]), 
        'end': int(row[3]), 
       }, 
       'target': { 
        'id': row[1], 
        'start': int(row[4]), 
        'end': int(row[5]), 
       }, 
      }]) 

    with open('data/data.txt', 'w') as outfile: 
     json.dump(data, outfile) 
+0

为什么要在列表中插入对象。使用[{source:{}}]会有什么用处? –

+0

@ElisByberi因为这是OP构建的字符串包含的内容。如果不需要,它会平均下降。不幸的是,OP没有给出和预期他们试图制作的产品或文件。 –

+0

是的,我看到了。无论如何,这个问题是无关紧要的。 –