Yank
Yank

Reputation: 748

How to just initialise the tile in python dictionary?

I try to generate JSON file from python dictionary data type.

Here is the segment of python code involved in this issue before I dump it to Json format :

channelSeg = {}
channelSeg["ch"] = None
channelSeg["chdata"] = []
for e in channelPkg:
    print e
    attr = e.split(':')
    if attr[0] == "ch":
        channel = attr[1].split(',')
        channelSeg["ch"] = int(channel[0])

Heading

I am doing this to init dictionary index then later I could append more data in my for loop like this:

channelSeg["ch"] = None
channelSeg["chdata"] = []

but I really want to do is without assign them any data just

channelSeg["ch"] 
channelSeg["chdata"]

but python doesn't like me to do that .

So after dump operation , I got repetitive Json data like this(part of it)

"datapkg": [
    {
        "dataseg": [
            {
                "ch": 0, 
                "chdata": [
                    {
                        "euler": {
                            "y": "-19.32", 
                            "x": "93.84", 
    "z": "-134.14"                        
                        }
                    }, 
                    {
                        "areal": {
                            "y": "57", 
                            "x": "-242", 
                            "z": "-210"
                        }
                    }
                ]
            }, 
            {
                "ch": 1, 
                "chdata": [
                    {
                        "areal": {
                            "y": "-63", 
                            "x": "-30", 
                            "z": "10"
                        }
                    }
                ]
            }, 
            {
                "ch": null, 
                "chdata": []
            }
        ], 
        "t": "174464", 
        "n": "9884"
    }, 

I always have redundant :

    {
        "ch": null, 
        "chdata": []
    }

Which make this JSON data package not healthy enough , is there anyway to remove this piece of redundant data?

Many thanks for any advices

===========v2==============

after I consider Edward's answer I found I could only solve it with channelSeg["ch"] = None but I don't know how to deal with another redundant list, it is because I didn't post enough code , so I past more complete code here , and still looking for solutions .. My code after modify :

       for elem in sensorPkg:
        channelPkg = elem.split('&') # channelPkg contain each channel's reading
        # each channel need a dictonary to store data
        channelSeg = {}
        # channelSeg["ch"] = None
        channelSeg["chdata"] = []

        for e in channelPkg:
            attr = e.split(':')
            if attr[0] == "ch":
                new_channel = {
                    'ch': int((attr[1].split(','))[0])
                    #channelSeg["ch"] = int(channel[0])
                }
                channelSeg["chdata"].append(new_channel)
                # store channel numbers
            elif attr[0] == "euler":
                # create euler package
                numbers = attr[1].split(',')
                eulerSeg = {}
                d = {}
                d["x"] = numbers[0]
                d["y"] = numbers[1]
                d["z"] = numbers[2]
                eulerSeg["euler"] = d
                # append to channel segement
                channelSeg["chdata"].append(eulerSeg)
            elif attr[0] == "areal": # real accelrometer readings
                # create areal package
                numbers = attr[1].split(',')
                arealSeg = {}
                d = {}
                d["x"] = numbers[0]
                d["y"] = numbers[1]
                d["z"] = numbers[2]
                arealSeg["areal"] = d 
                # append to channel segement
                channelSeg["chdata"].append(arealSeg)
            #and so on

and here is the outcome

 {
        "dataseg": [
            {
                "chdata": [
                    {
                        "ch": 0
                    }, 
                    {
                        "euler": {
                            "y": "6.51", 
                            "x": "73.16", 
                            "z": "-133.69"
                        }
                    }, 
                    {
                        "areal": {
                            "y": "516", 
                            "x": "-330", 
                            "z": "-7"
                        }
                    }
                ]
            }, 
            {
                "chdata": [
                    {
                        "ch": 1
                    }, 
                    {
                        "euler": {
                            "y": "24.86", 
                            "x": "4.30", 
                            "z": "-71.39"
                        }
                    }, 
                    {
                        "areal": {
                            "y": "120", 
                            "x": "316", 
                            "z": "273"
                        }
                    }
                ]
            }, 
            {
                "chdata": [
                    {
                        "ch": 2
                    }, 
                    {
                        "euler": {
                            "y": "62.32", 
                            "x": "-60.34", 
                            "z": "-120.82"
                        }
                    }, 
                    {
                        "areal": {
                            "y": "440", 
                            "x": "-611", 
                            "z": "816"
                        }
                    }
                ]
            }, 
            {
                "chdata": []
            }
        ], 
        "t": "14275", 
        "n": "794"
    }, 

which

                {
                "chdata": []
            }

Still there

Upvotes: 0

Views: 77

Answers (2)

Edward Newell
Edward Newell

Reputation: 18489

In the data structure that you're working with, I notice that 'dataseg' is a list of channels. Now, you don't need to initialize each channel before adding it to dataseg. First initialize dataseg as an empty list, then, while iterating over your entries in channelPkg, you can create new channel dicts using the information read from channelPkg, and append them immediately:

dataseg = []
for e in channelPkg:
    attr = e.split(':')
    if attr[0] == "ch":
        new_channel = {
            'ch': int(attr[1].split(',')),
            'data': []
        }
        dataseg.append(new_channel)

Hope that helps -- I'm not sure what the context of your question is exactly, so comment if this doesn't solve your problem.

Edit

I think that your problem is that the very last channelPkg is empty. So, for e in channelPkg: is equivalent to for e in [], and as a result, the last iteration of the outer loop appends just the initialized values (nothing inside for e in channelPkg executes).

Try adding two lines to test if the sensorPkg has a ch property (I'm assuming that all valid sensorPkgs have a ch property):

for elem in sensorPkg:

    channelPkg = elem.split('&') 

    # Add this to prevent appending an empty channel
    if 'ch' not in [e.split(':')[0] for e in channelPkg]:
        break

    channelSeg = {}
    channelSeg["chdata"] = []

    for e in channelPkg:
        # ... etc

Upvotes: 2

Alexander
Alexander

Reputation: 109626

Try using a conditional dictionary comprehension:

channelSeg["chdata"] = {ch.split(',')[0] if ch for ch in e.split(':')}

Upvotes: 0

Related Questions