【问题标题】:Parsing file in order to create a dictionary解析文件以创建字典
【发布时间】:2020-01-01 11:26:50
【问题描述】:

我正在使用的文本文件

Al:dog-walking:2:painting:1
Bob:dog-walking:1:knife-sharpening:3
Carol:cleanup:1:dog-walking:2:painting:1

想要返回的字典看起来像

{('Al','dog-walking'): 2,
('Al','painting'): 1,
('Bob','dog-walking'): 1,
('Bob','knife-sharpening'): 3,
('Carol','cleanup'): 1,
('Carol','dog-walking'): 2,
('Carol','painting'): 1}

这是我当前的代码,它产生了几乎正确的结果

def readdb(file):             
    d = defaultdict(int)
    for line in open('formelol'):
        f=line.strip().split(':')
        c=f[0]
        x=tuple((c,f[1]))
        z=tuple((c,f[3]))
        d[x]=int(f[2])
        d[z]=int(f[4])
    return d

print(readdb(file='formelol'))

返回:

{('Al', 'dog-walking'): 2, 
('Al', 'painting'): 1, 
('Bob', 'dog-walking'): 1, 
('Bob', 'knife-sharpening'): 3, 
('Carol', 'cleanup'): 1, 
('Carol', 'dog-walking'): 2})

我错过了('Carol','painting'): 1}的最后一行

对我来说,这段代码有点硬编码。

我的问题是,是否有更 Pythonic 的方式来产生这些结果,如果有,我该怎么做?

【问题讨论】:

    标签: python file dictionary


    【解决方案1】:

    您可以拆分每一行并使用扩展解包来分隔名称,然后将剩余的所有内容配对并分配给普通的dict,例如:

    d = {}
    with open('your_file_name') as fin:
        for line in fin:
            name, *rest = line.split(':')
            for activity, number in zip(rest[::2], rest[1::2]):
                d[(name, activity)] = int(number)
    

    这会给你一个d 的:

    {('Al', 'dog-walking'): 2,
     ('Al', 'painting'): 1,
     ('Bob', 'dog-walking'): 1,
     ('Bob', 'knife-sharpening'): 3,
     ('Carol', 'cleanup'): 1,
     ('Carol', 'dog-walking'): 2,
     ('Carol', 'painting'): 1}
    

    【讨论】:

      【解决方案2】:

      您的用例不需要 defaultdict。

      我会替换

      f=line.strip().split(':')
      c=f[0]
      x=tuple((c,f[1]))
      z=tuple((c,f[3]))
      d[x]=int(f[2])
      d[z]=int(f[4])
      

      k0, *rest = line.strip().split(':')
      for k1, v in zip(rest[::2], rest[1::2]):
         d[(k0, k1)] = int(v)
      

      【讨论】:

      • 好像不行。由于第三行的值比第一行多。我犯了一个错误,认为我的结果是正确的
      【解决方案3】:

      另一种解决方案是从数组中提取替代元素并创建字典。

      d = {}
      for line in open('formelol'):
          f=line.strip().split(':')
          name= f[0]
          values = f[1:]
          for i in range(len(values[1::2])):
              d[(name, values[0::2][i])] = values[1::2][i]
      d
      

      它会给你以下结果。

      {('Al', 'dog-walking'): '2',
       ('Al', 'painting'): '1',
       ('Bob', 'dog-walking'): '1',
       ('Bob', 'knife-sharpening'): '3',
       ('Carol', 'cleanup'): '1',
       ('Carol', 'dog-walking'): '2',
       ('Carol', 'painting'): '1'}
      

      【讨论】:

        【解决方案4】:

        你可以使用zip()函数:

        s = '''Al:dog-walking:2:painting:1
        Bob:dog-walking:1:knife-sharpening:3
        Carol:cleanup:1:dog-walking:2:painting:1'''
        
        d = {}
        for line in s.splitlines():
            l = line.split(':')
            for i, j in zip(l[1::2], l[2::2]):
                d[(l[0], i)] = int(j)
        print(d)
        

        打印:

        {('Al', 'dog-walking'): 2, ('Al', 'painting'): 1, ('Bob', 'dog-walking'): 1, ('Bob', 'knife-sharpening'): 3, ('Carol', 'cleanup'): 1, ('Carol', 'dog-walking'): 2, ('Carol', 'painting'): 1}
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-07-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-06-08
          • 1970-01-01
          • 2016-09-03
          相关资源
          最近更新 更多