可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm trying to iterate over a dictionary that I have defined in a specific order, but it always iterates in a different order than what I have defined in my code. This is just a basic example of what I'm trying to do. The dictionary I'm iterating over is much larger, has much more complexly named keys, and is not in alphabetical/numerical order.
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'
I need the order that I define the dictionary in to be preserved during iteration. My order is not alphabetical, so sorting alphabetically wouldn't really help. Is there any way to do this? I've tried `level_lookup.items(), but that doesn't maintain my order either.
回答1:
You should use an OrderedDict. It works exactly the way you want it, however you need to define it that way. Alternatively, you can have a list of keys in order, and iterate through the list and access the dictionary. Something along the lines of:
level_lookup_order = ['PRIORITY_1', 'PRIORITY_2', ...]
for key in level_lookup_order:
if key in level_lookup:
do_stuff(level_lookup[key])
This will be a pain to maintain, though, so I recommend you just use the OrderedDict.
As a last option, you could use 'constants'. Like,
PRIORITY_1 = 1
PRIORITY_2 = 2
...
lookup_order = {PRIORITY_1: 42, PRIORITY_2: 24, ...}
回答2:
If you're fine with using the key-sorted order:
for key in sorted(level_lookup.keys()):
...
That's what I generally do if the dict
is provided to me, and not something I instantiate (rather than OrderedDict
.
回答3:
You could use a collections.OrderedDict
. If that doesn't work for you, you could sort the keys before you iterate over them:
for k in sorted(myDict, lambda k: int(k.rsplit("_",1)[1]):
# do stuff
Note however, that this particular sorting costs linear space and O(nlogn) time. Also, it uses the coincidental numbering system "PRIORITY_N"
for sorting, which may not always be valid
回答4:
Try;
for priority in sorted(level_lookup.iterkeys()):
As Jon has pointed out, keys()
and iterkeys()
are redundant here;
for priority in sorted(level_lookup):
回答5:
I think you would be better off not using a containg dictionary and see no compelling reason to use one in this case. Alist
would store the items in the desired order:
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
In fact, you could write the whole thing as list comprehension:
set_levels = ('\n'.join('PRIORITY_{!s}'.format(level)
for level, priority in enumerate(level_lookup, start=1)
if priority['value'] == 'TRUE'))
print set_levels