user2761030
user2761030

Reputation: 1485

Error defining an OrderedDict - ValueError: too many values to unpack

I've been trying to define a couple OrderedDict objects all afternoon, but getting the ValueError message.

from collections import OrderedDict

personA = OrderedDict([(u'score',
                    OrderedDict([ (u'2015-09-09 03:40:33 +0100', 2646), 
                                  (u'2015-09-10 03:35:34 +0100', 2646), 
                                ]),
      OrderedDict([(u'adjusted_score',
                    OrderedDict([ (u'2015-09-09 03:40:33 +0100', 3646), 
                                  (u'2015-09-10 03:35:34 +0100', 3646), 
                                ])
                   )])
      )])

personB = OrderedDict([(u'score', 
                    OrderedDict([ (u'2015-09-11 03:40:33 +0100', 4646), 
                                  (u'2015-09-12 03:35:34 +0100', 4646), 
                                ]),
      OrderedDict([(u'adjusted_score',
                    OrderedDict([ (u'2015-09-11 03:40:33 +0100', 5646), 
                                  (u'2015-09-12 03:35:34 +0100', 5646), 
                                ]),
                    )])
      )])

Running this returns:

$ python ordereddict.py
Traceback (most recent call last):
  File "ordereddict.py", line 23, in <module>
    (u'2015-09-10 03:35:34 +0100', 3646), 
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/collections.py", line 52, in __init__
    self.__update(*args, **kwds)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/_abcoll.py", line 547, in update
    for key, value in other:
ValueError: too many values to unpack 

The end goal is to try to merge these two nested objects, but right now I'm stumped on even defining them!

Upvotes: 4

Views: 4223

Answers (2)

pat
pat

Reputation: 12749

The outer OrderedDicts are not being given a list of pairs. You are passing 3-tuples. Try

from collections import OrderedDict

personA = OrderedDict([
            (u'score',
             OrderedDict([ (u'2015-09-09 03:40:33 +0100', 2646), 
                        (u'2015-09-10 03:35:34 +0100', 2646), 
                         ])),
            (u'adjusted_score',
             OrderedDict([ (u'2015-09-09 03:40:33 +0100', 3646), 
                           (u'2015-09-10 03:35:34 +0100', 3646), 
                         ]))
            ])

personB = OrderedDict([
            (u'score', 
             OrderedDict([ (u'2015-09-11 03:40:33 +0100', 4646), 
                           (u'2015-09-12 03:35:34 +0100', 4646), 
                         ])),
            (u'adjusted_score',
             OrderedDict([ (u'2015-09-11 03:40:33 +0100', 5646), 
                           (u'2015-09-12 03:35:34 +0100', 5646), 
                         ])),
             ])

Upvotes: 1

ely
ely

Reputation: 77464

When using a list input to OrderedDict, it is expected to be of the form of an association list, such as [(key1, val1), (key2, val2), ...].

Let's just consider personA. For this OrderedDict, you start off correctly with the list having u'score' as a key and

OrderedDict([(u'2015-09-09 03:40:33 +0100', 2646), 
             (u'2015-09-10 03:35:34 +0100', 2646), 
            ])

as the value.

But notice that you don't give the enclosing right parenthesis after that value. Instead, you give just a comma, and then begin on what will be the next key-value entry in the constructor list.

So the first issue is that you need an additional ) coming just after the end of the first key-value pair, to make that a 2-tuple.

Next, when you start off with the second key-value pair, you start off with a whole new OrderedDict, but this isn't what you want. What you want is for u'adjusted_score' to be a key, inside of a 2-element key-value tuple. Making this change also lets you get rid of one redundant set of the closing delimiters.

So overall it will be:

In [10]: personA = OrderedDict([
             (u'score',
              OrderedDict([(u'2015-09-09 03:40:33 +0100', 2646), 
                           (u'2015-09-10 03:35:34 +0100', 2646), 
                          ])
             ), # <-- this was missing for 2-tuple

             (u'adjusted_score',
              OrderedDict([(u'2015-09-09 03:40:33 +0100', 3646), 
                           (u'2015-09-10 03:35:34 +0100', 3646), 
                          ])
             )
        ] # <-- Closes the list passed in the constructor
) # <-- Closes the open parenthesis from the "OrderedDict(" constructor. 

In [11]: personA
Out[11]: OrderedDict([(u'score', OrderedDict([(u'2015-09-09 03:40:33 +0100', 2646), (u'2015-09-10 03:35:34 +0100', 2646)])), (u'adjusted_score', OrderedDict([(u'2015-09-09 03:40:33 +0100', 3646), (u'2015-09-10 03:35:34 +0100', 3646)]))])

The particular error message you are seeing is due to the fact that in your original code, the overall tuple inside of the list passed to the OrderedDict constructor has more than just 2 elements, and the internal constructor logic of OrderedDict does not know how to handle an "association list" as input when the "associations" inside the list have more than just the expected two elements (the key and the value).

Upvotes: 4

Related Questions