簡體   English   中英

通過python中的嵌套列表進行二進制搜索

[英]Binary search through nested list in python

我有一個家庭作業問題:

編寫一個名為 readCountries 的函數,它讀取一個文件並返回一個國家列表。 應該從這個文件 (countries.txt) 中讀取國家/地區,其中包含不完整的國家/地區及其面積和人口列表。 此文件中的每一行代表一個國家,格式如下:

 name, area(in km2), population

打開文件時,您的函數應處理可能發生的任何異常。 你的函數應該完全讀入文件,並將數據分成一個二維列表。 您可能需要根據需要拆分和剝離數據。 數字應轉換為正確的類型。 您的函數應返回此列表,以便您可以在其余問題中使用它。

我有一個名為“countries.txt”的文本文件,其中包含一堆國家、地區和人口的列表。

“countries.txt”示例:

Afghanistan,    647500.0,   25500100
Albania,    28748.0,    2821977
Algeria,    2381740.0,  38700000

這是我擁有的代碼並且它有效:

def readCountries(filename):
    '''read a file and print it to the screen'''
    countryList = []
    for line in open(filename):
        with open(filename) as aFile:
            countries = aFile.read()
            countryList.append(line.strip().split())
    aFile.close()

    return countryList 

我運行問題時的輸出示例:

>>> countryList = readCountries("countries.txt")
>>> countryList
[['Afghanistan,', '647500.0,', '25500100'], ['Albania,', '28748.0,', '2821977'], ['Algeria,', '2381740.0,', '38700000']

下一個問題問:

編寫一個名為 printCountry 的函數,它接受一個代表國家名稱的字符串作為參數。 首先調用問題 1 中的答案以獲取國家/地區列表,然后對列表進行二分搜索,如果找到,則打印該國家/地區的信息。 並且應該打印出來:

 printCountry("Canada") Canada, Area: 9976140.0, Population: 35295770 printCountry("Winterfell") I'm sorry, could not find Winterfell in the country list.

但我想不通。

當我嘗試為這個問題進行編碼時,我輸入了:

countryList = readCountries("countries.txt")  
def printCountry(name):
    lo, hi = 0, len(countryList) - 1
    while lo <= hi:
        mid = lo + (hi - lo) // 2
        country = countryList[mid]
        test_name = country[0]
        if name > test_name:
            lo = mid + 1
        elif name < test_name:
            hi = mid - 1
        else:
            return country[0] + ", Area: " + str(country[1]) + ",    Population: " + str(country[2])
    return "I'm sorry can not find " + str(name)

結果是:

>>> printCountry("Canada")
'Sorry can not find Canada'

即使加拿大在文本中。 我哪里做錯了?

您的二進制搜索代碼(大部分)沒問題,但是您的代碼中存在一些問題,可以讀取國家/地區列表。

你的文件打開和閱讀代碼很奇怪。 這就像您結合了兩種不同的數據讀取方法,因此您要多次打開文件。

幸運的是,這些行的效果:

with open(filename) as aFile:
    countries = aFile.read()

不影響輸出readCountries工作,因為你沒有做任何其他countries

此外,在您的作業描述中,它說“根據需要剝離數據。數字應轉換為正確的類型”,而您的代碼沒有這樣做。 正如我上面的提示所暗示的那樣,這意味着您列表中的國家/地區名稱仍然帶有逗號,因此二進制搜索無法找到它們(除非您在搜索名稱中包含逗號)。

無論如何,這里有一個經過清理的版本,旨在在 Python 2.6 或更高版本上運行。

from __future__ import print_function

def readCountries(filename):
    countryList = []
    with open(filename) as aFile:
        for line in aFile:
            line = line.strip().split()
            #Remove anny trailing commas from each field
            line = [s.rstrip(',') for s in line]
            #Convert area to float and population to int
            line = [line[0], float(line[1]), int(line[2])]
            #print line
            countryList.append(line)
    return countryList

countryList = readCountries("countries.txt")

def printCountry(name):
    lo, hi = 0, len(countryList) - 1
    while lo <= hi:
        mid = lo + (hi - lo) // 2
        country = countryList[mid]
        test_name = country[0]
        if name > test_name:
            lo = mid + 1
        elif name < test_name:
            hi = mid - 1
        else:
            print('  {0}, Area: {1}, Population: {2}'.format(*country))
            break
    else:
        print("  I'm sorry, could not find {0} in the country list.".format(name))

#tests
printCountry("Canada")
printCountry("Winterfell")

print('- ' * 20)

#make sure we can find the first & last countries.
printCountry("Afghanistan")
printCountry("Nowhere")

這是我運行它的數據文件:

國家.txt

Afghanistan,    647500.0,   25500100
Albania,    28748.0,    2821977
Algeria,    2381740.0,  38700000
Canada,     9976140.0,  35295770
Nowhere,    1000.0      2345678

這是它產生的輸出:

  Canada, Area: 9976140.0, Population: 35295770
  I'm sorry, could not find Winterfell in the country list.
- - - - - - - - - - - - - - - - - - - - 
  Afghanistan, Area: 647500.0, Population: 25500100
  Nowhere, Area: 1000.0, Population: 2345678

確保在對列表進行二進制搜索之前對列表進行排序:

countryList.sort()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM