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'')])
>>>