让我们首先确保我们清楚字典是什么以及它可以用来做什么(希望我不要把脚放在嘴里——我自己对 Python 还很陌生)。
关于字典
在 Python 中, a将单个键dict
映射到单个值。您可以根据需要阅读文档,但这里的一个问题是您似乎希望将单个键映射到所需结果中的多个值:
{'ff:dd': 1, 2, 48000, qw:er, xc:sd}, {'io:uv': 1, 0, 56000}
这显示了两个字典。查看第一个字典, 仅{'ff:dd': 1,
将键映射'ff:dd'
到值1
;逗号表示,继续下一key:value
对。所以其余的被解释为键2
并48000
映射到无值(抛出SyntaxError
),未定义的名称qw
并xc
映射到未定义的名称er
和(如果你走那么远sd
就会抛出)。NameError
您可能意味着 forqw:er
和xc:sd
to 是字符串,在这种情况下,它们将被视为未映射到任何 value 的键,例如数字2
和48000
之前的数字。您可以在 shell 中对此进行测试:
>>> {'key':'value'} # A dict with one key, that has a value
{'key': 'value'}
>>> {'key'} # Curly braces can make a dict or a set
set(['key'])
>>> {'key1':'val1', 'key2'} # A dict needs to have values for each key
SyntaxError: invalid syntax
>>> {'key1':'val1', 'key2':} # Even an "empty" value has to be explicit
SyntaxError: invalid syntax
如果您出于某种原因想要在知道它们的值之前定义您的键,则使用零或空字符串可能是可行的,但“正确”的方法可能是使用dict.fromkeys()
:
>>> {'key1':None, 'key2':'', 'key3':0} # One of these might do the job...
{'key3': 0, 'key2': '', 'key1': None}
>>> dict.fromkeys(['key1','key2', 'key3']) # ...but this is probably better.
{'key3': None, 'key2': None, 'key1': None}
(作为旁注,您可能不想谈论“附加”到字典。这是您对有序列表所做的事情,例如 by mylist.append(myvalue)
。字典没有append()
方法;您所做的是设置一个键,如果键不存在,则创建它。“追加”表示添加到末尾,但字典是无序的,因此它们没有“结尾”。)
存储您的数据
现在,我将对您要尝试做什么做一个假设qw:er, xc:sd
,因为您的问题并不完全清楚。我的假设是,您只是想要一个发送到的响应列表'ff:dd'
。如果你愿意,你可以做其他事情,但在这个假设下,我会尝试阐明如何做一些你想做的事情。看起来您想要的结果类似于:
traffic = { 'ff:dd': { 'reqfrom':1, 'respto':2, 'reqvals':[48000],
'responders':['qw:er', 'xc:sd'] },
'io:uv': { 'reqfrom':1, 'respto':0, 'reqvals':[56000],
'responders':[] }
}
在字典的顶层traffic
,有两个键:'ff:dd'
和'io:uv'
。每个键的值是另一个字典,因此您可以访问来自键的请求数、对键的响应以及与该特定地址关联的其他值,如下所示:
>>> traffic['io:uv']['reqfrom'] # How many requests from 'io:uv'?
1
>>> traffic['ff:dd']['responders'] # What are the responses to 'ff:dd'?
['qw:er', 'xc:sd']
那么,如何动态存储这些值呢?通常,您只需为键分配一个值,例如mydict['key'] = 'value'
. 如果 key 已经存在,则 key 的 value 将被更新;如果没有,键值对将被添加到字典中。但是由于您的第一个键的值本身就是字典,所以有点棘手。
尝试这个...
这是使用上述假设结构的一种可能方法的示例。我不会详细介绍,因为更有经验的 Python 用户可能会向您展示做同样事情的更好方法。试试这个代码的大小 - 运行它,阅读它,打破它等。你应该能够弄清楚如何根据你的目的调整它。
traffic = {}
packets = (('0.000', 'ff:dd', 'ff:ff', '4', '126', '48000'),
('0.001', 'sd:fg', 'er:sd', '5', '125', '67000'),
('0.002', 'qw:er', 'ff:dd', '5', '127', '90000'),
('0.003', 'xc:sd', 'ff:dd', '5', '127', '90000'),
('0.004', 'io:uv', 'gh:ij', '4', '126', '56000'))
def record_packet(packet):
if packet[3] == '4': # Request
# Set up the key-value if it doesn't exist
if packet[1] not in traffic:
traffic[packet[1]] = {'reqfrom':0,
'respto':0,
'reqvals':[],
'responders':[]
}
traffic[packet[1]]['reqfrom'] += 1
traffic[packet[1]]['reqvals'].append(packet[5])
elif packet[3] == '5': # Response
# Record the response IFF there has been a request
if packet[2] in traffic:
traffic[packet[2]]['respto'] += 1
traffic[packet[2]]['responders'].append(packet[1])
else:
# Handle weirdness here
pass
for packet in packets:
record_packet(packet)
for key in traffic:
for item in traffic[key]:
print "traffic['{0}']['{1}'] has value: {2}".format(key, item, traffic[key][item])