ordereddict dict python-3.3

python-3.3 - ordereddict to json



Iterar sobre OrderedDict python (4)

¿Cómo iterar de un extremo a otro sobre OrderDedDict?

Ya sea:

z = OrderedDict( ... ) for item in z.items()[::-1]: # operate on item

O:

z = OrderedDict( ... ) for item in reversed(z.items()): # operate on item

Tengo el siguiente OrderedDict:

OrderedDict([(''r'', 1), (''s'', 1), (''a'', 1), (''n'', 1), (''y'', 1)])

Esto realmente presenta una frecuencia de una letra en una palabra.

En el primer paso, tomaría los dos últimos elementos para crear una tupla de unión como esta;

pair1 = list.popitem() pair2 = list.popitem() merge_list = (pair1[0],pair2[0]) new_pair = {} new_pair[merge_list] = str(pair1[1] + pair2[1]) list.update(new_pair);

Esto creó para mí la siguiente lista ordenada:

OrderedDict([(''r'', 1), (''s'', 1), (''a'', 1), ((''y'', ''n''), ''2'')])

Ahora me gustaría recorrer los elementos, cada vez tomando los últimos tres y decidiendo, en base a la suma más baja de los valores, cuál es el objeto de la unión.

Por ejemplo, la lista anterior se convertirá en;

OrderedDict([(''r'', 1), ((''s'', ''a''), ''2''), ((''y'', ''n''), ''2'')])

pero lo anterior fue:

OrderedDict([ (''r'', 1), (''s'', 2), (''a'', 1), ((''y'', ''n''), ''2'')])

El resultado sería:

OrderedDict([(''r'', 1), (''s'', 2), ((''a'',''y'', ''n''), ''3'')])

Como quiero que los de la izquierda tengan el menor valor.

Intenté hacerlo yo mismo, pero no entiendo cómo repetir de un extremo a otro sobre OrderDict.

¿Cómo puedo hacerlo?

Editado respondiendo el comentario:

Obtengo un diccionario de frecuencia de una letra en una oración:

{ ''s'':1, ''a'':1, ''n'':1, ''y'': 1}

y la necesidad de crear un árbol huffman de ella.

por ejemplo:

((s,a),(n,y))

Estoy usando python 3.3


Ejemplo simple

from collections import OrderedDict d = collections.OrderedDict() d[''a''] = 1 d[''b''] = 2 d[''c''] = 3 for key, value in d.items(): print key, value

Salida:

a 1 b 2 c 3


Puedes iterar usando enumerate e iteritems :

dict = OrderedDict() # ... for i, (key, value) in enumerate(dict.iteritems()): # Do what you want here


Tenga en cuenta que, como se indica en los comentarios de adsmith , esta es probablemente una instancia de un problema XY y debe reconsiderar sus estructuras de datos.

Dicho esto, si necesita operar solo en los últimos tres elementos, entonces no necesita iterar. Por ejemplo:

MergeInfo = namedtuple(''MergeInfo'', [''sum'', ''toMerge1'', ''toMerge2'', ''toCopy'']) def mergeLastThree(letters): if len(letters) < 3: return False last = letters.popitem() last_1 = letters.popitem() last_2 = letters.popitem() sum01 = MergeInfo(int(last[1]) + int(last_1[1]), last, last_1, last_2) sum12 = MergeInfo(int(last_1[1]) + int(last_2[1]), last_1, last_2, last) sum02 = MergeInfo(int(last[1]) + int(last_2[1]), last, last_2, last_1) mergeInfo = min((sum01, sum12, sum02), key = lambda s: s.sum) merged = ((mergeInfo.toMerge1[0], mergeInfo.toMerge2[0]), str(mergeInfo.sum)) letters[merged[0]] = merged[1] letters[mergeInfo.toCopy[0]] = mergeInfo.toCopy[1] return True

Entonces teniendo

letters = OrderedDict([(''r'', 1), (''s'', 1), (''a'', 1), (''n'', 1), (''y'', 1)]) print letters mergeLastThree(letters) print letters mergeLastThree(letters) print letters

Produce:

>>> OrderedDict([(''r'', 1), (''s'', 1), (''a'', 1), (''n'', 1), (''y'', 1)]) OrderedDict([(''r'', 1), (''s'', 1), ((''y'', ''n''), ''2''), (''a'', 1)]) OrderedDict([(''r'', 1), ((''a'', ''s''), ''2''), ((''y'', ''n''), ''2'')])

Y para fusionar toda la estructura completamente solo necesitas:

print letters while mergeLastThree(letters): pass print letters

Lo que da:

>>> OrderedDict([(''r'', 1), (''s'', 1), (''a'', 1), (''n'', 1), (''y'', 1)]) OrderedDict([(((''a'', ''s''), ''r''), ''3''), ((''y'', ''n''), ''2'')]) >>>