读/写一个文件,其中每一行都是字典的列表



我想这样做:

  f = open(genes_path, 'w')
  for key, genes in key_genes.iteritems():
      f.write(key)
      for gene in genes:
          f.write(",t"+gene)
      f.write("n")
  f.close()

得到这个:

key1、AT3G32920、AT3G33187、AT3G32940、AT3G32930、AT3G32980、AT3G32960

key2, AT3G32920, AT3G33187, AT3G32940, AT3G32930,

其中键可以是任何字符串(不带逗号),顺序在任何地方都无关紧要(我使用来自boltons和lists的OrderedMultiDict用于打印方便,但它真的无关紧要,可以是dict和set,因为我关心),并且每行可以有不同数量的元素。

我似乎找不到任何模块来完成这个非常简单的任务。dictwwriter需要列/字段名,所以这不能回答我的问题。Numpy只适用于矩形数组和填充引入了太多不必要的东西。我知道自己编写循环很容易,但我只是觉得这是足够常见的东西,它应该有自己的内置。

有时候我只需要给别人发送大列表的东西(像基因给不编程的人),这样他们就可以把它拉到excel中添加或删除元素,然后发送回来,我不需要做任何其他事情。

谁知道有一个模块的功能,自动读取和写入这些粗糙的字典列表文件?或者是否有一个很好的理由让它不存在?

我在想一些非常简单的东西,比如pandas.read_csv(path, delimiter=",")pandas.DataFrame.to_csv(path, delimiter=",")


<

原理/strong>

我之所以挑剔它是一个模块的单个函数,而不是我可以非常在纯python中轻松完成的东西,不是因为我懒惰,而是因为当你使用具有良好文档的模块中的某些东西时,人们更容易查看代码并找出确切的意图。即使任务很琐碎,你仍然可以降低代码的复杂性。我看到编写自己的函数作为特定于域的东西,而一个共同的读写例程应该是你import的东西,如果可用,最好使用。这是蟒蛇之禅的一部分,对吧?所以第二个问题实际上是问"这是一个特定于领域的任务吗?",因为在我看来并不是这样。

您可以将每一行构建成一个字符串,并进行一次写入:

with open(genes_path, 'w') as f:
    for key, genes in key_genes.iteritems():
        f.write("n".join(",t".join([key] + genes)))

这仍然是你自己做,但它比你发布的代码更简洁。

首先,我看不出你原来的循环有什么不好(你可以把它变成一个函数,并缩短使用with上下文管理器)。然而,我提到了csv模块,因为它似乎做几乎你所需要的,没有DictWriter需要。

我假设你是这样开始的:

In [4]: key_genes
Out[4]: 
{'key1': ['AT3G32920',
  'AT3G33187',
  'AT3G32940',
  'AT3G32930',
  'AT3G32980',
  'AT3G32960'],
 'key2': ['AT3G32920', 'AT3G33187', 'AT3G32940', 'AT3G32930'],
 'key3': ['AT3G32920',
  'AT3G33187',
  'AT3G32940',
  'AT3G32930',
  'AT3G32980',
  'AT3G32960'],
 'key4': ['AT3G32920', 'AT3G33187', 'AT3G32940', 'AT3G32930']}

所以这个代码:

with open('out.csv', 'wb') as outfile:
    writer = csv.writer(outfile)
    for key, genes in key_genes.iteritems():
        writer.writerow([key] + genes)

生产:

key3,AT3G32920,AT3G33187,AT3G32940,AT3G32930,AT3G32980,AT3G32960
key2,AT3G32920,AT3G33187,AT3G32940,AT3G32930
key1,AT3G32920,AT3G33187,AT3G32940,AT3G32930,AT3G32980,AT3G32960
key4,AT3G32920,AT3G33187,AT3G32940,AT3G32930

显然如果你想对键进行排序你可以这样做你的键将被排序,因为你使用的是有序结构而我使用的是普通的内置字典。现在我们进入几乎部分的需求。您使用,t作为分隔符。如果您尝试使用csv.writer这样做,它会抱怨分隔符应该是一个字符。这对我来说是有意义的,因为csv文件通常是逗号分隔的,或者是制表符分隔的,而不是两者都用。分隔符的存在只是为了方便机器处理,并且机器只需要一个字符(在其他任何地方都不会出现未加引号的字符)就可以完成。

所以我的最终答案是:如果您可以使用一个字符分隔符(对于正常的CSV处理,这应该不是问题),请使用csv模块。否则,使用短循环

最新更新