开发者

List in a dictionary, looping in Python

I have the following code:

    TYPES = {'hotmail':{'type':'hotmail', 'lookup':'mixed', 'dkim': 'no', 'signatures':['|S|Return-Path: postmaster@hotmail.com开发者_如何学JAVA','|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

However, it generates the error:

for sig in sub_type['signatures']:
TypeError: string indices must be integers, not str

I assume that it would see the list being pulled from dictionary element, and allow me to loop over that?

Python newbie is a newbie :(


for type_key, type in TYPES.iteritems():
    for sub_type_key, sub_type in type.iteritems():
        for sig in sub_type['signatures']:

should be:

for type_key, type in TYPES.iteritems():
        for sig in type['signatures']:

But 'type' is a poor name choice in this case... you don't want to shadow a builtin.

Essentially, 'type_key' has the name (either 'hotmail' or 'gmail'), and 'type' has the dictionary that is the value associated with that key. So type['signatures'] is what you're wanting.

Also, you may not need to have 'gmail' inside the nested dictionary; just return 'type_key' instead of type['type'].

Bringing it all together, maybe this will work better: (Warning: untested)

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


[Posted as an answer instead of a comment because retracile beat me to the answer, but the formatting is still a point worth making.]

Laying out the data helps to visualize it:

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', '', '', ''],
  },
}

Note: You can have an ending comma after the last item in a dict, list, or tuple (used above only for the dicts—it's not always more clear), and you don't have to worry about screwing around with that comma, which is a Good Thing™.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜