Search code examples
pythonenumerate

(Python) Index stops after finding one element in the row


I have a map that my program scans and tries to find out where the occurrences of "E" are in the map, then stores them accordingly. But as it stands, if there are two occurrences of "E" in the same row it only indexes the first one? How can I get around this with my current function?

def agent_loc(a_maze):
 coor_list = str()
 for row, i in enumerate(a_maze):
      try:
           column = i.index("E")
      except:
           continue

      coor_list = coor_list + str(row) + ";" + str(column) + "|"
 print (coor_list)

Solution

  • You only have one loop, over the rows.

    And within that loop, you call index only once. So, if there's a second "E" after that first one, you're never going to find it.

    What you need is another loop, that loops over all the "E"s. For example:

    def agent_loc(a_maze):
        coor_list = str()
        for row, i in enumerate(a_maze):
             column = -1
             try:
                 while True:
                      column = i.index("E", column+1)
                      coor_list = coor_list + str(row) + ";" + str(column) + "|"
             except ValueError:
                 pass
        print(coor_list)
    

    This would probably be a lot easier to read if you factored out the inner loop:

    def find_all(haystack, needle):
        pos = -1
        try:
            while True:
                yield haystack.index(needle, pos+1)
        except ValueError:
            pass
    
    def agent_loc(a_maze):
        coor_list = str()
        for row, i in enumerate(a_maze):
             for column in find_all(i, "E"):
                 coor_list = coor_list + str(row) + ";" + str(column) + "|"
        print(coor_list)
    

    Or just rewrote it to loop over all characters:

    def agent_loc(a_maze):
        coor_list = str()
        for row, i in enumerate(a_maze):
             for column, j in enumerate(i):
                 if j == "E":
                     coor_list = coor_list + str(row) + ";" + str(column) + "|"
        print(coor_list)
    

    Once you do that, you've almost got a comprehension. So, let's rewrite it to use a comprehension:

    def agent_loc(a_maze):
        matches = (str(row) + ";" + str(column) 
                   for row, i in enumerate(a_maze) 
                   for column, j in enumerate(i)
                   if j == "E")
        print("|".join(matches) + "|")