将文件读入python字典

时间:2013-10-28 00:52:16

标签: python

我有一个像这样的文本文件

128.220.251.50
130.79.48.57
203.110.240.191
128.220.251.50 208.94.63.193
128.36.233.154 
128.36.233.154 131.246.112.29
128.36.233.154 136.145.115.196
130.79.48.57 203.110.240.191
131.246.112.29 199.26.254.68
136.145.115.196 128.220.251.50
136.145.115.196 140.247.60.123
137.165.1.113 
137.165.1.113 128.220.251.50
137.165.1.113 128.36.233.154
137.165.1.113 130.79.48.57
140.247.60.123 137.165.1.113
199.26.254.68 136.145.115.196
203.110.240.191 131.246.112.29
208.94.63.193 140.247.60.123

我想把它读成字典。这是代码。

def get_key_value(line):
  key, sep, value = line.strip().partition(" ")

  return key, value

with open("output.txt") as fd:    
    d = dict(get_key_value(line) for line in fd)

for key,value in d.iteritems():
    print str(key),str(value)

以下是print语句的输出。

128.220.251.50 208.94.63.193
130.79.48.57 203.110.240.191
203.110.240.191 131.246.112.29
131.246.112.29 199.26.254.68
199.26.254.68 136.145.115.196
136.145.115.196 140.247.60.123
128.36.233.154 136.145.115.196
140.247.60.123 137.165.1.113
208.94.63.193 140.247.60.123
137.165.1.113 130.79.48.57

我有以下问题。如果你考虑输入,有三个键(或行)用137.165.1.113表示。但是print语句只打印其中一个。 并非所有键值对都保存在字典中。 而且我想要忽略输入中只有一个ip地址的行,这在此代码中完成。谢谢。

3 个答案:

答案 0 :(得分:2)

字典不能那样工作。为具有值的键指定值时,将覆盖先前的值。

也许尝试将每个字典值设为一个列表,然后可以将其附加到:

d = {}
with open("output.txt") as fd:
    for line in fd:
        if not line.count(' '): continue # Skip over non-splittable lines
        for k,v in line.split():
            if k in d:
                d[k].append(v)
            else:
                d[k] = [v] 

for key,value in d.iteritems():
    print str(key), " ".join(value))

答案 1 :(得分:1)

Python字典是集合:键必须是唯一的,你不能有多个equals键。如果您尝试分配一个已经存在的密钥,它将被覆盖(事实上,您将该密钥的最后一行作为值)。
http://docs.python.org/2/tutorial/datastructures.html#dictionaries

您可以将列表用作值,并附加新值或使用MultiDicts,允许多个相等键的特殊词典。

答案 2 :(得分:0)

使用toolz library

的功能性解决方案
$ pip install toolz
$ python

>>> from toolz import groupby, valmap, first, second

>>> with open(filename) as f:
...     lines = [line.strip().split(' ') for line in f if ' ' in line]

>>> groupby(first, lines)
{'128.220.251.50': [['128.220.251.50', '208.94.63.193']],
 '128.36.233.154': [['128.36.233.154', '131.246.112.29'], ['128.36.233.154', '136.145.115.196']],
 '130.79.48.57': [['130.79.48.57', '203.110.240.191']],
 '131.246.112.29': [['131.246.112.29', '199.26.254.68']],
 '136.145.115.196': [['136.145.115.196', '128.220.251.50'], ['136.145.115.196', '140.247.60.123']],
 '137.165.1.113': [['137.165.1.113', '128.220.251.50'], ['137.165.1.113', '128.36.233.154'], ['137.165.1.113', '130.79.48.57']],
 '140.247.60.123': [['140.247.60.123', '137.165.1.113']],
 '199.26.254.68': [['199.26.254.68', '136.145.115.196']],
 '203.110.240.191': [['203.110.240.191', '131.246.112.29']],
 '208.94.63.193': [['208.94.63.193', '140.247.60.123']]}

>>> valmap(lambda L: map(second, L), _)
{'128.220.251.50': ['208.94.63.193'],
 '128.36.233.154': ['131.246.112.29', '136.145.115.196'],
 '130.79.48.57': ['203.110.240.191'],
 '131.246.112.29': ['199.26.254.68'],
 '136.145.115.196': ['128.220.251.50', '140.247.60.123'],
 '137.165.1.113': ['128.220.251.50', '128.36.233.154', '130.79.48.57'],
 '140.247.60.123': ['137.165.1.113'],
 '199.26.254.68': ['136.145.115.196'],
 '203.110.240.191': ['131.246.112.29'],
 '208.94.63.193': ['140.247.60.123']}