Why the loop isn't deleting my specific number?

Question:

Can someone help me, my code was working fine until I put a loop that checks and deletes an array if it includes "0.00000000" by the second index, it doesn’t work and sometimes writes "list index out of range" what’s the problem? Thank you in advance, and here is my code:

parse = json.loads(message) 
sum = len(parse["b"])
for x in range(sum):
    if (parse["b"][x][1] == "0.00000000"):
        del parse["b"][x]

My json:

{
   "U":26450991840,
   "u":26450991976,
   "b":[
      [
         "20640.59000000",
         "0.00000000"
      ],
      [
         "20640.15000000",
         "0.08415000"
      ],
      [
         "20640.14000000",
         "0.05144000"
      ],
      [
         "20640.13000000",
         "0.00519000"
      ],
      [
         "20640.12000000",
         "0.00000000"
      ],
      [
         "20640.11000000",
         "0.00000000"
      ],
      [
         "20640.10000000",
         "0.00000000"
      ]
   ]
}

I tried to make a script that checks all the json string converting it in dictionary by using python library and deleting all the arrays containing "0.00000000"

Asked By: rizy

||

Answers:

When the first del occurs, your list size changes and your indexes are then invalidated. You can overcome that problem by traversing the list in reverse

myjson = {
   "U":26450991840,
   "u":26450991976,
   "b":[
      [
         "20640.59000000",
         "0.00000000"
      ],
      [
         "20640.15000000",
         "0.08415000"
      ],
      [
         "20640.14000000",
         "0.05144000"
      ],
      [
         "20640.13000000",
         "0.00519000"
      ],
      [
         "20640.12000000",
         "0.00000000"
      ],
      [
         "20640.11000000",
         "0.00000000"
      ],
      [
         "20640.10000000",
         "0.00000000"
      ]
   ]
}

blist = myjson['b']

for i in range(len(blist)-1, -1, -1):
    if blist[i][1] == "0.00000000":
        del blist[i]

print(myjson)

Output:

{'U': 26450991840, 'u': 26450991976, 'b': [['20640.15000000', '0.08415000'], ['20640.14000000', '0.05144000'], ['20640.13000000', '0.00519000']]}

Of course that’s an in situ modification of the original dictionary. If you want a new dictionary then:

mynewdict = {}

for k, v in myjson.items():
    if k != 'b':
        mynewdict[k] = v
    else:
        for e in v:
            if e[1] != "0.00000000":
                mynewdict.setdefault(k, []).append(e)

print(mynewdict)
Answered By: OldBill

Referring to the JSON that you’ve provided, when you run this code, you set sum to be 7, ie, x in the for loop takes value 0, 1, 2, 3, 4, 5, and 6.

However, before the execution of the for loop is completed, you modify parse["b"] and delete some values in the list, thereby reducing the size of it. It is now less than 7. So, when the loop reaches an index value that is no longer present in the list, it throws an IndexError.

To better understand this, run:

parse = json.loads(message) 
sum = len(parse["b"])
print(f"Original length of list: {sum}")
for x in range(sum):
    print(f"Current value of index (x): {x}")
    print(f"Current length of list (parse['b']): {len(parse['b'])}")
    if (parse["b"][x][1] == "0.00000000"):
        del parse["b"][x]
Answered By: doobeedoobee

As the other answers have indicated, you cannot delete elements from the array that you are currently iterating – it’s length is modified.

Here’s a solution that generates a completely new list:

parse["b"] = [ x for x in parse["b"] if x[1] != "0.00000000" ]  

Above, we use a list comprehension to just skip all elements of parse["b"] that have a "0.0000000" at index 1.

Answered By: Mark
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.