如何按定义的顺序迭代Python字典?

时间:2013-07-16 17:24:12

标签: python loops dictionary

我正在尝试迭代我按特定顺序定义的字典,但它总是以与我在代码中定义的顺序不同的顺序迭代。这只是我正在尝试做的一个基本的例子。我正在迭代的字典要大得多,命名密钥要复杂得多,而且不按字母/数字顺序排列。

level_lookup = \
{
'PRIORITY_1' :   { 'level' : 'BAD',   'value' :   ''  },
'PRIORITY_2' :   { 'level' : 'BAD',   'value' :   ''  },
'PRIORITY_3' :   { 'level' : 'BAD',   'value' :   ''  },
'PRIORITY_4' :   { 'level' : 'BAD',   'value' :   ''  },
'PRIORITY_5' :   { 'level' : 'CHECK', 'value' :   ''  },
'PRIORITY_6' :   { 'level' : 'CHECK', 'value' :   ''  },
'PRIORITY_7' :   { 'level' : 'GOOD',  'value' :   ''  },
'PRIORITY_8' :   { 'level' : 'GOOD',  'value' :   ''  },
}

for priority in level_lookup:
    if( level_lookup[ priority ][ 'value' ] == 'TRUE' ):
        set_levels += str( priority ) + '\n'

我需要在迭代期间保存我定义字典的顺序。我的订单不是按字母顺序排列的,因此按字母顺序排序并不会有所帮助。有没有办法做到这一点?我试过`level_lookup.items(),但这也不能保持我的订单。

5 个答案:

答案 0 :(得分:9)

您应该使用OrderedDict。它完全按照您的方式工作,但您需要以这种方式定义它。或者,您可以按顺序获得键列表,并遍历列表并访问字典。有点像:

level_lookup_order = ['PRIORITY_1', 'PRIORITY_2', ...]
for key in level_lookup_order:
    if key in level_lookup:
        do_stuff(level_lookup[key])

但这样做很难维护,所以我建议你只使用OrderedDict。

作为最后一个选项,您可以使用'常量'。像,

PRIORITY_1 = 1
PRIORITY_2 = 2
...
lookup_order = {PRIORITY_1: 42, PRIORITY_2: 24, ...}

答案 1 :(得分:6)

如果你使用按键排序的顺序没问题:

for key in sorted(level_lookup.keys()):
    ...

如果dict提供给我,我通常会这样做,而不是我实例化的(而不是OrderedDict

答案 2 :(得分:4)

可以使用collections.OrderedDict。如果这对你不起作用,你可以在迭代之前对键进行排序:

for k in sorted(myDict, lambda k: int(k.rsplit("_",1)[1]):
    # do stuff

但请注意,此特定排序会花费线性空间和O(nlogn)时间。此外,它使用巧合编号系统"PRIORITY_N"进行排序,这可能并不总是有效

答案 3 :(得分:2)

尝试;

for priority in sorted(level_lookup.iterkeys()):

正如乔恩所指出的那样,keys()iterkeys()在这里是多余的;

for priority in sorted(level_lookup):

答案 4 :(得分:0)

我认为使用包含字典的会更好,并且在这种情况下没有令人信服的理由使用它。 list会按所需顺序存储项目:

level_lookup = [
    {'level': 'BAD',   'value': ''    },
    {'level': 'BAD',   'value': ''    },
    {'level': 'BAD',   'value': ''    },
    {'level': 'BAD',   'value': ''    },
    {'level': 'CHECK', 'value': 'TRUE'},
    {'level': 'CHECK', 'value': 'TRUE'},
    {'level': 'GOOD',  'value': ''    },
    {'level': 'GOOD',  'value': ''    },
]

set_levels = ''
for level, priority in enumerate(level_lookup, start=1):
    if priority['value'] == 'TRUE':
        set_levels += 'PRIORITY_{!s}\n'.format(level)
print set_levels

事实上,你可以把整个事情写成列表理解:

set_levels = ('\n'.join('PRIORITY_{!s}'.format(level)
                for level, priority in enumerate(level_lookup, start=1)
                    if priority['value'] == 'TRUE'))
print set_levels