16

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

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(),但这也不能维持我的秩序。

4

5 回答 5

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, ...}
于 2013-07-16T17:51:30.307 回答
6

如果您可以使用键排序顺序:

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

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

于 2013-07-16T17:26:41.783 回答
4

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

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

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

于 2013-07-16T17:25:32.180 回答
2

尝试;

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

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

for priority in sorted(level_lookup):
于 2013-07-16T17:26:34.040 回答
0

我认为您最好不要使用包含字典,并且在这种情况下看不到使用包含字典的令人信服的理由。Alist将以所需的顺序存储项目:

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
于 2013-07-16T19:47:08.023 回答