2015-07-28 7 views
3

Я пишу код, чтобы найти широты и долготы, и рассчитать расстояние в пределах определенного радиуса точки и отделить два файла.python skipping for for

Для первых 5 итераций программа работает нормально, но после этого программа не проходит через внутренний цикл for. Я прошел через код, он просто перешагивает цикл for. Кажется, это зависит от того, что я установил переменной radius. Если radius меньше, это позволит меньше повторений внутреннего цикла for.

Я боюсь, что это может быть проблемой того, как я читаю в файле. Я считаю, что после 5-й итерации infile_2 пуст, но я не могу понять, как это исправить.

def main(): 

    global infile_1, infile_2 

    ## import geocoded college dataset 
    infile_2 = open("university_FIPS.csv", "r") 

    ## import great_lakes_sample 
    infile_1 = open("great_lakes_sample.csv", "r") 
    outfile_within_bound = open("great_lakes_blood_college", "w") 
    outfile_outside_bound = open("great_lakes_blood_NOcollege", "w") 
    inside_buffer_count = 0 
    outside_buffer_count = 0 

    global lat_1_index, long_1_index, lat_2_index, long_2_index 

    ## set radius to desired length (in miles) 
    radius = 100 



    ## when it is generalized, use this: 
    ## radius = input_buffer_radius() 


    # create two subsets of blood drive data, one within 
    # radius of college, one outside 

    # skip header 
    n_1 = 0 
    for infile_1_line in infile_1: 
     infile_1_line = infile_1_line.strip().replace("\"", "").split(","), 
     infile_1_line = infile_1_line[0]   

     record_stored = False 

     # find index of lat_2, long_2 
     if(n_1 == 0): 
      lat_2_index = infile_1_line.index("lat") 
      long_2_index = infile_1_line.index("long") 
      infile_1_header_list = infile_1_line 

     # assign lat_2, long_2 latitude and longitude values 
     lat_2 = infile_1_line[ lat_2_index ] 
     long_2 = infile_1_line[ long_2_index ] 

     # skip header 
     if n_1 > 0: 
      print("\n\nExamining Record:", n_1) 

      try: 
       lat_2 = float(lat_2) 
       long_2 = float(long_2) 
      except ValueError: 
       print("Value error, skipping record") 
       continue       
      except TypeError: 
       print("Type error, skipping record") 
       continue 
      print("Coordinates for record:", lat_2, long_2) 


      # skip header 
      n_2 = 0 


      # WILL NOT ENTER LOOP ON THIRD ITERATION, it's dependent on radius, when radius is 100, it stops at n_1 = 6 
      if (n_1 > 0): 
       print("\n\n\nbefore loop")    

      for infile_2_line in infile_2: 
       infile_2_line = infile_2_line.strip().split(",")               

       if (n_2 == 0): 
        print("in") 


       # find index of lat_1, long_1, create header list 
       if(n_2 == 0 and n_1 == 1): 
        lat_1_index = infile_2_line.index("lat") 
        long_1_index = infile_2_line.index("long") 
        infile_2_header_list = infile_2_line 

        # creat headers for each outfile 
        write_to_csv(infile_1_header_list, outfile_within_bound) 
        write_to_csv(infile_1_header_list, outfile_outside_bound) 


       # assign values for lat_1, long_1, after header 
       if(n_2 > 0): 
        lat_1 = infile_2_line[ lat_1_index ] 
        long_1 = infile_2_line[ long_1_index ] 

        try: 
         lat_1 = float(lat_1) 
         long_1 = float(long_1) 
         value_error = False 
        except ValueError: 
         continue 
        except TypeError: 
         continue 

        dist = haversine_distance(lat_1, long_1, lat_2, long_2) 

        if(dist <= radius): 
         print("\nRecord", n_1, "is", 
           dist, "miles from", lat_1, long_1) 
         write_to_csv(infile_1_line, outfile_within_bound) 
         record_stored = True 
         print("Record stored in outfile_inside_bound.") 
         print("Moving to next record.") 
         inside_buffer_count += 1 
         break 

       n_2 += 1 

      if(record_stored == False): 

       print("\nOutside buffer.") 
       write_to_csv(infile_1_line, outfile_outside_bound) 
       outside_buffer_count += 1 
       print("Record stored in outfile_outside_bound.") 


     n_1 += 1 

    print("\nRecords within buffer:", inside_buffer_count, "\nRecords outside buffer:", outside_buffer_count) 
    infile_1.close() 
    infile_1.close() 
    outfile_within_bound.close() 
    outfile_outside_bound.close() 

ответ

3

Прямой ответ, когда вы перебирать файла в цикле в for x in f стиле, питон на самом деле отслеживания того, как далеко в файл вы идете. Поэтому, если вы выполняете 10 итераций внутреннего цикла до достижения точки прерывания, в следующий раз, когда вы попытаетесь выполнить итерацию через файл с помощью infile_2, вы запустите 10 строк в файл!

Похоже, что в вашем случае на третьей итерации вы прочитали весь файл, поэтому итератор infile_2 будет просто сидеть в конце файла на всех последующих итерациях внешнего цикла. Легкое исправление заключается в том, чтобы сделать infile_2.seek(0) перед тем, как выполняется цикл внутреннего цикла. Это приведет к изменению позиции infile_2, чтобы снова просмотреть начало файла. Уф ...

Это все хорошо и денди, но я хотел бы предложить несколько вещей для вас:

  1. При открытии файлов используйте with open("test.txt","r") as f, как показано на this SO post. Это дает вам возможность не забывать закрывать файл явно, поскольку он закрывается неявно в конце блока.

  2. Часто лучше читать файл в списке, выполнять вычисления, а затем записывать результаты всего за один снимок. Это делает ваш код более организованным (также более простым для чтения), а также позволяет избежать ошибок, подобных тому, с которым вы работаете.

Для иллюстрации этих стратегий вот как я бы читать файлы в вашем примере кода:

def main(): 
    global infile_1, infile_2 

    with open("great_lakes_sample.csv", "r") as infile_1: 
     #List comprehension to format all of the lines correctly 
     infile1_lines = [line.strip().replace("\"", "").split(",") for line in infile_1] 

    with open("university_FIPS.csv", "r") as infile_2: 
     #List comprehension to format all of the lines correctly 
     infile2_lines = [line.strip().split(",") for line in infile_2] 

    #Both files are automatically closed when their respected with blocks end. 

 Смежные вопросы

  • Нет связанных вопросов^_^