0

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

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 说明。但是打印语句只打印其中一个。并非所有键值对都保存在字典中。而且我希望忽略输入中只有一个 IP 地址的行,这是在此代码中完成的。提前致谢。

4

3 回答 3

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))
于 2013-10-28T00:55:15.800 回答
1

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

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

于 2013-10-28T01:08:53.727 回答
0

使用toolz库的功能解决方案

$ 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']}
于 2013-10-28T01:39:22.193 回答