在Python中循环字典中的列表
我有以下这段代码:
TYPES = {'hotmail':{'type':'hotmail', 'lookup':'mixed', 'dkim': 'no', 'signatures':['|S|Return-Path: postmaster@hotmail.com','|R|^Return-Path:\s*[^@]+@(?:hot|msn)','^Received: from .*hotmail.com$']},
'gmail':{'type':'gmail', 'lookup':'mixed', 'dkim': 'yes', 'signatures':['|S|Subject: unsubscribe','','','']}
}
for type_key, type in TYPES.iteritems():
for sub_type_key, sub_type in type.iteritems():
for sig in sub_type['signatures']:
if ("|S|" in sig):
#String based matching
clean_sig = sig[3:len(sig)]
if (clean_sig in file_contents):
sig_match += 1
elif ("|R|" in sig):
clean_sig = sig[3:len(sig)]
#REGMATCH later
if (sig_match == sig.count):
return sub_type['type']
return None
但是,它出现了这个错误:
for sig in sub_type['signatures']:
TypeError: string indices must be integers, not str
我想这段代码应该能看到从字典元素中提取的列表,然后让我可以对它进行循环处理,对吧?
刚学Python的我真是个菜鸟 :(
2 个回答
3
这个内容是作为答案发布的,而不是评论,因为retracile先给出了答案,不过这里的格式还是值得提一下。
把数据整理出来可以帮助我们更好地理解它:
TYPES = {
'hotmail': {
'type': 'hotmail',
'lookup': 'mixed',
'dkim': 'no',
'signatures': ['|S|Return-Path: postmaster@hotmail.com',
'|R|^Return-Path:\s*[^@]+@(?:hot|msn)',
'^Received: from .*hotmail.com$'],
},
'gmail': {
'type': 'gmail',
'lookup': 'mixed',
'dkim': 'yes',
'signatures': ['|S|Subject: unsubscribe', '', '', ''],
},
}
注意:在字典、列表或元组的最后一个项目后面可以加一个逗号(上面只在字典中用了这个),这样做并不总是更清晰,但你不需要担心这个逗号的问题,这是一件好事™。
7
for type_key, type in TYPES.iteritems():
for sub_type_key, sub_type in type.iteritems():
for sig in sub_type['signatures']:
应该是:
for type_key, type in TYPES.iteritems():
for sig in type['signatures']:
不过在这种情况下,'type'这个名字不太好...你不想覆盖一个内置的名称。
简单来说,'type_key'是名字(要么是'hotmail',要么是'gmail'),而'type'是和这个名字相关联的字典。所以你需要的是type['signatures']。
另外,你可能不需要在嵌套字典里放'gmail';直接返回'type_key'就可以了,而不是type['type']
。
把这些结合起来,也许这样会更好用:(警告:未经测试)
providers = {
'hotmail':{
'type':'hotmail',
'lookup':'mixed',
'dkim': 'no',
'signatures':[
'|S|Return-Path: postmaster@hotmail.com',
'|R|^Return-Path:\s*[^@]+@(?:hot|msn)',
'^Received: from .*hotmail.com$']
},
'gmail':{
'type':'gmail',
'lookup':'mixed',
'dkim': 'yes',
'signatures':['|S|Subject: unsubscribe','','','']
}
}
for provider, provider_info in providers.iteritems():
for sig in provicer_info['signatures']:
if ("|S|" in sig):
#String based matching
clean_sig = sig[3:len(sig)]
if (clean_sig in file_contents):
sig_match += 1
elif ("|R|" in sig):
clean_sig = sig[3:len(sig)]
#REGMATCH later
if (sig_match == sig.count):
return provider
return None