Home > other >  python - nested loops robust to nulls/blanks
python - nested loops robust to nulls/blanks

Time:07-28

Here's a slice of my data:

[
['2002','','28','102','5'],
['2003','32','15','88','2'],
]

A year followed by four possible types: A,B,C,D, I want to loop through each of these so that I get a 'long' form of data, ex:

{'year':'2002','type':B}x28 (28 of these)
{'year':'2002','type':C}x102
{'year':'2002','type':D}x5

And so forth; note that the first occurrence of A should be skipped because it has a blank.

I got:

Invalid literal int() with base 10:''

Which is odd because I made sure to cast the readout into an int using int():

master_array = []
for i in range(len(tsv_data)):
    for j in range(int(tsv_data[i][1])):
        temp = {}
        temp['type']='A'
        master_array.append(temp)

I just moved on and tried:

master_array = []
for i in range(len(tsv_data)):
    try:
        for j in range(int(tsv_data[i][1])):
            temp = {}
            temp['type']='A'
            temp['year']=tsv_data[i][0]
            master_array.append(temp)
    except:
        try:
            for j in range(int(tsv_data[i][2])):
                temp = {}
                temp['type']='B'
                temp['year']=tsv_data[i][0]
                master_array.append(temp)
        except:
            try:
                for j in range(int(tsv_data[i][3])):
                    temp = {}
                    temp['type']='C'
                    temp['year']=tsv_data[i][0]
                    master_array.append(temp)
            except:
                for j in range(int(tsv_data[i][4])):
                    temp = {}
                    temp['type']='D'
                    temp['year']=tsv_data[i][0]
                    master_array.append(temp)

Which ran, but it gave me a tiny fraction of what the actually list should be. The behavior I was expect was for try/except to skip all the ones with blanks and iterate over the cells with values.

Question

How can I read the values in each cell and use them as iteration cues for my master_array and robust to blanks?

The result should be one item for each year and type configuration, based on whatever the value was.

CodePudding user response:

Only take the range if the value is actual digits. This does that and is a more simple and readable implementation.

master_array = []
for y, a, b, c, d in tsv_data:
    if a.isdigit():
        master_array.extend([{"year": y, "type": "A"} for _ in range(int(a))])
    if b.isdigit():
        master_array.extend([{"year": y, "type": "B"} for _ in range(int(b))])
    if c.isdigit():
        master_array.extend([{"year": y, "type": "C"} for _ in range(int(c))])
    if d.isdigit():
        master_array.extend([{"year": y, "type": "D"} for _ in range(int(d))])

You could do this with the simpler truth check, but it is better to check it is a digit before the conversion.

    if a:  # Will work, but better to check int.
        master_array.extend([{"year": y, "type": "A"} for _ in range(int(a))])
  • Related