Search code examples
pythonlistdictionaryiteration

Iterating through dict and list2d, list_value gets replaced with a str


I am iterating through a dict and after that through a 2d list[list[float|int] then i am changing the values of the list2d to the corresponding in the dict randomly a str appears

from the test i did it changes based on the size of the list2d example:

50, 50 = 13, 49

80, 80 = 15, 48

terrain_probability_dict: {float | int, str} = {-1: "e", 0.2 : "o", 0.5 : "M", 1 : "#"}
def generate_terrain(world: list[list[float | int]]):

    keys = sorted(terrain_probability_dict.keys())
    for i in range(1, len(keys)):
        for y in range(len(world)):
            for x in range(len(world[0])):
                if keys[i - 1] < world[y][x] <= keys[i]:
                    world[y][x] = terrain_probability_dict[keys[i]]

how i checked it:

for y in range(len(world)):
    for x in range(len(world[0])):
        # Print only if the type of the current value is string

        if isinstance(world[y][x], str):
            print(f"Initial value at world[{y}][{x}]: {world[y][x]} (Type: {type(world[y][x])})")
        #and
        print(y, x)

Before the iteration and also the if isinstance code in the iteration From the prints i got that there is a "M" or "o" in the list when iterating

Why does a index in world change to int in the world

the error after about 15*50 iteration(depending on the list size):

if keys[i - 1] < current_value <= keys[i]:
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '<' not supported between instances of 'float' and 'str'

Solution

  • You're assigning strings to world[y][x] after checking if the prior value was in an interval. Unfortunately, that breaks when you check the next interval. You probably shouldn't be using the same list of lists for both the input and output.

    If you had type-checked your code, the type checker would have objected, as you're passing a 2d list of numbers into a function that says it expects list[list[str]]. Some of the function's code expects numbers and other parts assign strings.

    If you really do want to transform the list of lists's inner type, you could probably reorder your loops and break out of the loop over the keys if you find one that matches (and perhaps do something else, like raising an exception, if you never find a match).