user8716125
user8716125

Reputation:

Python - why is this a malformed node or string?

I was just tidying up some code and ran into some trouble. I am getting an error I have never come across before

ValueError: malformed node or string:['0.000', '37.903', 'nosing']

My openLabels function at the top works fine and returns a list of items structured as you can see in the error message. I am doing some debugging and found it is the labelsToFrames function throwing the error. It is not accepting my list of lists as input. I have no idea why.

Any direction would be much appreciated!

def openLabels(pathLabels):
    path = (pathLabels + "*.lab")
    files = glob.glob(path)

    textCorpus = []
    for name in files:
        try:
            with open(name) as f:
                for line in f:
                    line = line.split()
                    textCorpus.append(line)

        except IOError as exc: 
            if exc.errno != errno.EISDIR:
                raise

    return textCorpus

def labelToFrames(labelCorpus):
    with labelCorpus as f_in:
        for line in f_in:
            song = ast.literal_eval(line)

        output = []                                 
        for block in song:
            block_start = float(block[0])           
            block_end = float(block[1])            
            singing = block[2]                      
            block_range = np.arange(block_start, block_end, 0.033)
        for x in block_range:
            ms_start = '{0:.3f}'.format(x)
            ms_end = '{0:.3f}'.format(x + 0.032)
            add_to_output = [ms_start, ms_end, singing]
            output.append(add_to_output)

        return(output)   


def main(): 
    pathLabels = "~/Train Labels/"
    labelCorpus = openLabels(pathLabels)
    labelCorpusFrames = labelToFrames(labelCorpus)

main()  


  File "<ipython-input-7-d1a356f3bed8>", line 1, in <module>
    labelCorpusFrames = labelToFrames(labelCorpus)

  File "<ipython-input-2-77bea44f1f3d>", line 54, in labelToFrames
    song = ast.literal_eval(line)

  File "*/lib/python3.6/ast.py", line 85, in literal_eval
    return _convert(node_or_string)

  File "*/lib/python3.6/ast.py", line 84, in _convert
    raise ValueError('malformed node or string: ' + repr(node))

ValueError: malformed node or string: ['0.000', '37.903', 'nosing']

Upvotes: 1

Views: 10140

Answers (2)

Matthew Champion
Matthew Champion

Reputation: 410

The issue is that labelCorpus is a list of lists. As such, when you're executing labelToFrames and passing in labelCorpus, it is iterating over the list of lists, assigning each individual list to line and then trying to run ast.literal_eval on line. This then fails because ast.literal_eval requires either a string or expression node, not a list.

The reason that labelCorpus is a list of lists comes from when it is assigned a value from the openLabels function. In the following section, you iterate over the file paths returned by glob.glob and open the files:

with open(name) as f:
    for line in f:
        line = line.split()
        textCorpus.append(line)

On each open file you're iterating over the individual lines and then splitting each line in the file (which returns a list) and assigning it back to the line variable, which you then append to the textCorpus list. This list of lists is then what you return from the function and assign to labelCorpus in main.

Upvotes: 0

YYC_Code
YYC_Code

Reputation: 45

I'm not at home so can't experiment at the moment but I believe the problem is the real numbers mixed in with the string. Try converting them to string first then pass them onto whatever function is utilizing them. I ran into this once a few months back and converting ahead of time was the answer.

Upvotes: 0

Related Questions