我正在尝试迭代我按特定顺序定义的字典,但它总是以与我在代码中定义的顺序不同的顺序迭代。这只是我正在尝试做的一个基本的例子。我正在迭代的字典要大得多,命名密钥要复杂得多,而且不按字母/数字顺序排列。
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(),但这也不能保持我的订单。
答案 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