Home > Blockchain >  Python, ValueError: not enough values to unpack (expected 2, got 1), Python OOP
Python, ValueError: not enough values to unpack (expected 2, got 1), Python OOP

Time:07-25

In this project, i was told to make a code where i should leverage the convenience of a dictionary to power a configuration file.

My following code looks like this:

class ConfigDict(dict):

    def __init__(self, filename):
        self._filename = filename
        if os.path.isfile(self._filename):
            with open(self._filename) as fh:
                for line in fh:
                    line = line.rstrip()
                    key, value = line.split('=', 1)
                    dict.__setitem__(self, key, value)    

    def __setitem__(self, key, value):
        dict.__setitem__(self, key, value)
        with open(self._filename, 'w') as fh:
            for key, val in self.items():
                fh.write('{0}={1}\n'.format(key, val))

cd = ConfigDict("Config_file.txt")

The problem arises when i try to run the code, with the specified file name, An error of "ValueError: not enough values to unpack (expected 2, got 1)", from this line of code:

key, value = line.split('=', 1)

I have searched for solutions regarding this particular problem but have never seem to find it, and your help would really benefit me.

CodePudding user response:

First, it would be great if you could share a few sample lines from your input file.

The reason you get the error is because line.split('=', 1) is not returning two values (key and value). What solution to go for depends on what you intend to do with the file.

If you are expecting only 2 values, then keep the code as is and check your files. I see you already leverage the maxsplit argument, which determines the maximum times to split:

key, value = line.split("=", maxsplit=1).

This will not only ensure that only a single split is done but also that it returns a list with 2 elements (at most) or less. Less is the issue here since the line you are reading doesn't have that many. Could it be the headline or a line containing other info that cannot be parsed using split? This is important because if you have any corrupt line with more than a single "=" symbol, then a ValueError will be thrown:

line = "1=2=3"
key, value = line.split("=")
> ValueError: too many values to unpack (expected 2)

And if you have less, then you will get the error you cited above.

If you have some corrupt lines with only <= 1 value to split, then a good course of action would be to ignore such lines altogether with a try/except block:

class ConfigDict(dict):

def __init__(self, filename):
    self._filename = filename
    if os.path.isfile(self._filename):
        with open(self._filename) as fh:
            for line in fh:
                line = line.rstrip()
                try:
                   key, value = line.split('=', 1)
                   dict.__setitem__(self, key, value)
                except ValueError:
                   pass

The code above will only set key/value pairs if the split was successful.

Your code otherwise seems perfectly fine.

CodePudding user response:

This error is because of a corner case. Suppose line = 'apple', then key,value = line.split('=', 1) will throw error.Your code is expecting two values but this corner case will return only one value hence the error "Value Error: not enough values to unpack (expected 2, got 1)".

  • Related