虽然循环导致CSV读取问题

时间:2017-05-31 14:45:30

标签: python csv while-loop

非常新的Python,我刚刚创建了我的第一段代码,以帮助我完成一项非常平凡的工作任务。一切都很顺利,直到我尝试将while循环与CSV读取结合起来,我只是不确定该去哪里。

我正在努力的代码:

airport = input('Please input the airport ICAO code: ')

with open('airport-codes.csv', encoding='Latin-1') as f:
    reader = csv.reader(f, delimiter=',')
    for row in reader:
        if airport.lower() == row[0].lower():
            airportCode = row[2] + "/" + row[0]
            print(airportCode)
        else:
            print('Sorry, I don\'t recognise that airport.')
            print('Please try again.')

执行此代码会导致'else'连续打印,直到代码停止,无论输入是否与CSV文件中的输入匹配。我删除此语句的那一刻代码运行正常(如果输入不匹配,则不会打印任何内容)。

我的目标是尝试做的是问题循环,直到真实。所以我的尝试如下:

with open('airport-codes.csv', encoding='Latin-1') as f:
    reader = csv.reader(f, delimiter=',')
    for row in reader:
        while True:
            airport = input('Please input the airport ICAO code: ')
            if airport.lower() == row[0].lower():
                airportCode = row[2] + "/" + row[0]
                print(airportCode)
                break
            else:
                print('Sorry, I don\'t recognise that airport.')
                print('Please try again.')
                False

我很确定我的有限经验导致我监督一个明显的问题,但我找不到与我的搜索查询类似的东西,所以我的下一站就在这里。

先谢谢,我为任何格式问题道歉。

根据要求,CSV文件的几行:

EDQO    small_airport   Ottengrüner Heide Airport  50.22583389, 11.73166656    
EDQP    small_airport   Rosenthal-Field Plössen Airport    49.86333466, 
EDQR    small_airport   Ebern-Sendelbach Airport    50.03944397, 10.82277775    
EDQS    small_airport   Suhl-Goldlauter Airport 50.63194275, 10.72749996    
EDQT    small_airport   Haßfurt-Schweinfurt Airport    50.01805496, 
EDQW    small_airport   Weiden in der Oberpfalz Airport 49.67890167, 

5 个答案:

答案 0 :(得分:0)

一个简单的解决方案是这样的:

airport = input('Please input the airport ICAO code: ')

airportCode = None
with open('airport-codes.csv', encoding='Latin-1') as f:

    reader = csv.reader(f, delimiter=',')
    for row in reader:
        if airport.lower() == row[0].lower():
            airportCode = row[2] + "/" + row[0]
            print(airportCode)
            break

if airportCode is not None:
    print('Sorry, I don\'t recognise that airport.')
    print('Please try again.')

答案 1 :(得分:0)

我有一个不同的建议使用函数:

for (Iterator i = c.iterator(); i.hasNext(); ) {
       Element e = i.next();    //Get the element
       System.out.println(e);    //access or modify the element
}

答案 2 :(得分:0)

最好先将整个CSV数据读入Python字典,而不是尝试将CS​​V中的每一行与输入的输入相匹配。这样您就可以轻松“查找”您喜欢的任何机场代码,而无需继续重读整个文件:

import csv

airport_codes = {}

with open('airport-codes.csv', encoding='Latin-1', newline='') as f_input:
    csv_input = csv.reader(f_input, delimiter='\t')

    for row in csv_input:
        if len(row) >= 2:    # Make sure the CSV line has at least 2 columns
            airport_codes[row[0].lower()] = row[2]

while True:   
    icao_code = input('Please input the airport ICAO code: ').lower().strip()

    try:
        print("{}/{}".format(row[0], airport_codes[icao_code]))
    except KeyError:
        print("Sorry, I don't recognise airport.")
        print("Please try again.\n")  

这样做会让你的脚本提示多个问题。

注意:您在问题中发布的数据似乎是制表符分隔的,如果是这种情况,则需要\t才能正确读取条目。如果newline=''语句将与documentation中显示的CSV阅读器一起使用,还建议您将open()添加到try语句中。

exceptexcept是所谓的异常处理,在这种情况下,如果您在字典中查找的条目不存在,则代码跳转到A = LOAD 'file_location' USING PigStorage('\t') AS (name:chararray, age:int, gpa:float); 部分。这是Python中的首选方法。

答案 3 :(得分:0)

我认为你的逻辑流程有点偏差。如果要继续循环遍历csv文件,直到找到机场代码,然后如果代码不存在则打印错误消息,那么我们需要以不同的顺序执行操作。目前,代码循环遍历文件的每一行。对于每一行,如果输入代码与csv文件中的任何机场代码都不匹配,它会打印出不存在的消息。相反,我们想要打印错误消息,如果它不在任何行中。我们也只想在整个循环中通过csv文件提示一个提示符。而不是:

with open('airport-codes.csv', encoding='Latin-1') as f:
    reader = csv.reader(f, delimiter=',')
    for row in reader: # Loop over every row in the csv
        while True: # This effectively keeps you in the loop until you 'break'
            airport = input('Please input the airport ICAO code: ')
            if airport.lower() == row[0].lower():
                airportCode = row[2] + "/" + row[0]
                print(airportCode)
                break # break if this row matches the airport code
            else:
                print('Sorry, I don\'t recognise that airport.')
                print('Please try again.') # Prints if this row doesn't match
                False # This doesn't set anything to 'False'

试试这个:

with open('airport-codes.csv', encoding='Latin-1') as f:
    reader = csv.reader(f, delimiter=',')
    while True:
        matches = False
        airport = input('Please input the airport ICAO code:')
        for row in reader:
            if airport.lower() == row[0].lower():
                airportCode = row[2] + "/" + row[0]
                print(airportCode)
                matches = True
                break
        if not matches:
            print('Sorry, I don\'t recognise that airport.')
            print('Please try again.')
            False 

使用此代码,流程是不同的。首先,要求机场代码。然后针对该文件进行检查,直到您到达文件末尾或找到匹配的代码。如果在文件中找到代码,请将其打印出来。如果找不到,请打印一条消息并再次询问用户新的机场代码。

答案 4 :(得分:0)

如果您想要按照自己的方式进行操作,只需确保当用户输入错误代码时,csv读者的指针会返回到文件的开头,例如:

with open('airport-codes.csv', encoding='Latin-1') as f:
    reader = csv.reader(f, delimiter=',')
    airportCode = None  # store for our code
    while not airportCode:  # loop until valid code found
        airport = input('Please input the airport ICAO code: ')  # ask for the code
        for row in reader:  # loop through our CSV
            if airport.lower() == row[0].lower():  # if code found in the first column...
                airportCode = row[2] + "/" + row[0]
                break  # no need to search further
        if not airportCode:  # we didn't find the code, print a helpful message
            print('Sorry, I don\'t recognise that airport.')
            print('Please try again.')
            f.seek(0)  # reset the CSV pointer to the beginning for the next loop
    print("Airport found: {}".format(airportCode))

但是我建议你只需将代码加载到内存中并在现场快速查找:

airportCode = None  # store for our code
airport_codes = {}  # our in-memory fast lookup
with open('airport-codes.csv', encoding='Latin-1') as f:
    reader = csv.reader(f, delimiter=',')
    for row in reader:  # loop through our CSV
        airport_codes[row[0].lower()] = row[2] + "/" + row[0]  # store the lookup map 
while not airportCode:
    airport = input('Please input the airport ICAO code: ')  # ask for the code
    airportCode = airport_codes.get(airport.lower(), None)
    if not airportCode:
        print('Sorry, I don\'t recognise that airport.')
        print('Please try again.')
print("Airport found: {}".format(airportCode))