Вопрос

I try to iterate over an ordered dictionary in last in first out order. While for a standard dictionary everything works fine, the first solution for the orderedDict reacts strange. It seems, that while popitem() returns one key/value pair (but somehow sequentially, since I can't replace kv_pair by two variables), iteration is finished then. I see no easy way to proceed to the next key/value pair.

While I found two working alternatives (shown below), both of them lack the elegance of the normal dictionary approach.

From what I found in the online help, it is impossible to decide, but I assume I have wrong expectations. Is there a more elgant approach?

from collections import OrderedDict

normaldict = {"0": "a0.csf", "1":"b1.csf", "2":"c2.csf"}

for k, v in normaldict.iteritems():
    print k,":",v

d = OrderedDict()
d["0"] = "a0.csf"
d["1"] = "b1.csf"
d["2"] = "c2.csf"

print d, "****"

for kv_pair in d.popitem():
    print kv_pair
print "++++"


for k in reversed(d.keys()):
    print k, d[k]

print "%%%%"

while len(d) > 0:
    k, v = d.popitem()
    print k, v
Это было полезно?

Решение

dict.popitem() is not the same thing as dict.iteritems(); it removes one pair from the dictionary as a tuple, and you are looping over that pair.

The most efficient method is to use a while loop instead; no need to call len(), just test against the dictionary itself, an empty dictionary is considered false:

while d:
    key, value = d.popitem()
    print key, value

The alternative is to use reversed():

for key, item in reversed(d.items()):
    print key, value

but that requires the whole dictionary to be copied into a list first.

However, if you were looking for a FIFO queue, use collections.deque() instead:

from collections import deque

d = deque(["a0.csf", "b1.csf", "c2.csf"])

while d:
    item = d.pop()

or use deque.reverse().

Другие советы

d.popitems() will return only one tuple (k,v). So your for loop is iterating over the one item and the loop ends.

you can try

while d:
    k, v = d.popitem()
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top