以pythonic方式从制表符分隔文件构建字典

时间:2013-04-27 11:22:20

标签: python list dictionary python-2.7

我编写了以下函数,该函数采用制表符分隔文件(作为字符串)并将其转换为字典,其中包含整数作为键和两个浮点数的列表以及值:

def parseResults(self, results):
    """
    Build a dictionary of the SKU (as key), current UK price and current Euro price
    """
    lines = results.split('\n')
    individual_results = []
    for i in range(1,len(lines)-1):
        individual_results.append(lines[i].split('\t'))
    results_dictionary = {}
    for i in range(len(individual_results)):
        results_dictionary[int(individual_results[i][0])] = [float(individual_results[i][1]), float(individual_results[i][2])]
    return results_dictionary

我一直在阅读有关使用列表理解和字典理解的内容,但我真的不知道构建它的最佳方法是什么。

我想我可以使用以下方法简化第一个列表构建:

individual_results = [results.split('\t') for results in lines[1:]]

但我不知道创建字典的最佳方法。我觉得这可能是一种简洁的方式,甚至没有创建中间列表。

谢谢,

马特

4 个答案:

答案 0 :(得分:5)

像这样:

import csv
import StringIO
results = "sku\tdelivered-price-gbp\tdelivered-price-euro\tid\n32850238\t15.53\t35.38\t258505\n"

data = list(csv.DictReader(StringIO.StringIO(results), delimiter='\t'))
print(data)

输出:

[{'sku': '32850238', 'delivered-price-euro': '35.38', 'delivered-price-gbp': '15.53', 'id': '258505'}]

当然,如果您可以从实际文件中读取,则可以跳过stringIO部分。

要构建所需的字典类型,您可以这样做:

data = {}
for entry in csv.DictReader(StringIO.StringIO(results), delimiter='\t'):
    data[entry['sku']] = [entry['delivered-price-gbp'], entry['delivered-price-euro']]

甚至作为字典理解:

import csv
import StringIO
results = "sku\tdelivered-price-gbp\tdelivered-price-euro\tid\n32850238\t15.53\t35.38\t258505\n10395850\t35.21\t46.32\t3240582\n"

data = {entry['sku']: [entry['delivered-price-gbp'], entry['delivered-price-euro']] 
        for entry in csv.DictReader(StringIO.StringIO(results), delimiter='\t')}
print(data)

但现在这很难读懂。

在最后两种情况下的输出是:

{'32850238': ['15.53', '35.38'], '10395850': ['35.21', '46.32']}

答案 1 :(得分:1)

使用标准库中的CSV模块,它具有直接读取字典的方法 csv.DictReader

答案 2 :(得分:0)

尝试这样的事情:

In [8]: from collections import defaultdict

In [9]: with open("filename") as f:
   ...:     dic=defaultdict(list)
   ...:     next(f)                #skip the first line 
   ...:     for line in f:
   ...:         k,v=line.split(None,1)
   ...:         dic[int(k)].extend( map(float,v.split()[:2]) )
   ...:         

In [10]: dic
Out[10]: defaultdict(<type 'list'>, {32850238: [15.53, 35.38]})

答案 3 :(得分:0)

您的代码可以简单地为:

def parseResults(self, results):  
    lines = results.split('\n')
    li_results = [x.split('\t') for x in lines]
    results_dict = {int(x[0]):map(float,[x[1],x[2]]) for x in li_results[1:]} # skip the header
    return results_dict

或者如果你想缩短它(不推荐):

def parseResults(self, results):
    return {int(x[0]):map(float,[x[1],x[2]]) for x in [i.split('\t') for i in results.split('\n')][1:]}

输出(来自你给出的字符串):

{32850238: [15.53, 35.38]}