可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a snippet of code which orders a dictionary alphabetically.
Is there a way to select the ith key in the ordered dictionary and return its corresponding value? i.e.
import collections
initial = dict(a=1, b=2, c=2, d=1, e=3)
ordered_dict = collections.OrderedDict(sorted(initial.items(), key=lambda t: t[0]))
print(ordered_dict)
OrderedDict([('a', 1), ('b', 2), ('c', 2), ('d', 1), ('e', 3)])
I want to have some function along the vein of...
select = int(input("Input dictionary index"))
#User inputs 2
#Program looks up the 2nd entry in ordered_dict (c in this case)
#And then returns the value of c (2 in this case)
How can this be achieved?
Thanks.
(Similar to Accessing Items In a ordereddict, but I only want to output the value of the key-value pair.)
回答1:
In Python 2:
If you want to access the key:
>>> ordered_dict.keys()[2]
'c'
If want to access the value:
>>> ordered_dict.values()[2]
2
If you're using Python 3, you can convert the KeysView
object returned by the keys
method by wrapping it as a list:
>>> list(ordered_dict.keys())[2]
'c'
>>> list(ordered_dict.values())[2]
2
Not the prettiest solution, but it works.
回答2:
Using itertools.islice
is efficient here, because we don't have to create any intermediate lists, for the sake of subscripting.
from itertools import islice
print(next(islice(ordered_dict.items(), 2, None)))
If you want just the value, you can do
print ordered_dict[next(islice(ordered_dict, 2, None))]
回答3:
Do you have to use an OrderedDict or do you just want a dict-like type that supports indexing? If the latter, then consider a sorted dict object. Some implementations of SortedDict (which orders pairs based on the key sort order) support fast n-th indexing. For example, the sortedcontainers project has a SortedDict type with random-access indexing.
In your case it would look something like:
>>> from sortedcontainers import SortedDict
>>> sorted_dict = SortedDict(a=1, b=2, c=2, d=1, e=3)
>>> print sorted_dict.iloc[2]
'c'
If you do a lot of lookups, this will be a lot faster than repeatedly iterating to the desired index.
回答4:
Don't underestimate just a plain 'ole for loop:
from collections import OrderedDict
od=OrderedDict([('a', 1), ('b', 2), ('c', 2), ('d', 1), ('e', 3)])
def ith(od, tgt):
for i, t in enumerate(od.items()):
if i==tgt:
print('element {}\'s key is "{}"'.format(i,t[0]))
break
else:
print('element {} not found'.format(tgt))
ith(od, 2)
# element 2's key is "c"
ith(od, 20)
# element 20 not found
The advantage here is that the loop will break as soon as the desired element is found and returns a sensible result if not found...
The disadvantage is that relative slices are not supported.
回答5:
You could do something along these lines (od is the ordered dict):
def get_idx(od, idx):
from itertools import islice
idx = (idx + len(od)) % len(od)
t = islice(od.items(), idx, idx + 1)
return next(t)
>>>x
OrderedDict([('a', 2), ('b', 3), ('k', 23), ('t', 41), ('q', 23)])
>>>get_idx(x, 1)
('b', 3)
>>>get_idx(x, 2)
('k', 23)
>>>get_idx(x, 4)
('q', 23)
>>>get_idx(x, -1)
('q', 23)
>>>get_idx(x, -2)
('t', 41)