Python帮助 - 字典、键、值

2 投票
3 回答
1142 浏览
提问于 2025-04-17 21:11

我正在尝试写一个程序,但遇到了很多麻烦。以下是我的指示:

这个程序的目标是从一些美国人口普查数据中创建一个简单的数据库。这个数据库将是一个字典,字典的键是州名,值是一个列表,包含从1900年到1990年每年的总人口。一旦你创建了这个数据库,你需要写一个简单的命令驱动程序,它会提示用户输入一个州名和一个年份,然后报告该州在那个年份的人口。程序会一直运行,直到用户输入任何以'q'或'Q'开头的单词。

人口普查数据在这里:http://www.census.gov/population/www/censusdata/files/urpop0090.txt。我已经把这些数据保存到一个名为“database”的普通文本文件中。

花点时间研究一下这个文件。里面有一些多余的信息(至少对我们来说是这样的)。你需要想出一个方法,从文件中提取出你需要的信息,以便放入你的数据库(字典)中。

以下是我描述所需信息的模式:

  1. 当一行以6个空格开头,并且后面跟着一个大写字母时,你可以判断这一行包含州的数据。你可以通过在这一行中找到两个连续的空格来确定州名的结束。

  2. 如果一行包含州的数据,你可以通过找到第43个字符,然后向前退,直到找到一个单独的空格,来找到这一行的第一个总人口。

  3. 如果一行包含州的数据,你可以通过找到第101个字符,然后向前退,直到找到一个单独的空格,来找到这一行的第二个总人口。

  4. 如果一行包含州的数据,你可以通过找到第159个字符,然后向前退,直到找到一个单独的空格,来找到这一行的第三个总人口。

这是我目前的进展:

#gets rid of commas in the populations 
def convert_string_to_number( comma_string ):
        number = comma_string.replace(",","")
        parts = number.split(".")  # check for a decimal point
        if len(parts) == 1 and parts[0].isdigit(): # we really have an integer
    number = float(parts[0])
        elif len(parts) == 2 and parts[0].isdigit() and parts[1].isdigit(): #float
    number = float (parts[0] + "." + parts[1])
        else:
    number = None
        return number


def getsub(str, endindex):
     sublist = str[:endindex].split(' ')
     substring = sublist[-1]
     return substring

def main():
    data = open('database', 'r')
lines = data.readlines()

for line in lines:
    # Now do the line processing.
    if line.startswith('      '):
    # Now process the state data
        firsttotalpop = getsub(line, 42)
        secondtotalpop = getsub(line, 100)
        thirdtotalpop = getsub(line, 158)


return 0

我在弄清楚如何实际创建一个包含键/值的字典,以及如何将人口值与州名的键关联起来时遇到了一些问题。此外,我不确定如何获取用户输入并将其用作键。我也不确定上面的代码是否正确获取了州名和人口信息。

任何建议或帮助都将非常感激!

3 个回答

0

给定的信息是:我们知道人口1从第34个字符开始,因为没有哪个州的人口超过1亿。我们还知道人口1会在第44个字符结束。

不过,有些州的人口少于1000万,所以它们必须从第35或第36个字符开始。这重要吗?不重要。

# where line is the line is containing STATE information
def get_population_one( line ):
    populationOne = line[34:44]
    populationOne = populationOne.replace(',','') # remove the commas
    populationOne = populationOne.replace(' ', '') # remove any spaces for states that start with less than 10 million population
    return int(populationOne) # convert the string to an integer 

接下来,对于人口2和人口3,你只需要改变州信息的索引,使用上面相同的逻辑就可以了。

这一切都可以用一行代码完成:

 def get_population_one(line):
     return int(line[34:44].replace(',', '').strip())
0

关于创建字典:

my_dict = {}
my_dict['Texas'] = [1,2,5,10,2000] #etc etc 
my_dict['Florida'] = [2,3,6 10, 1000] #etc etc

你也可以这样做,

temp = 'Florida'
print my_dict[temp]

你可以按照自己喜欢的方式存储数据,但一般的写法是 dict[key] = value,其中 key 可以是一个整数或字符串(在你的情况下是字符串),而 value 可以是几乎任何数据结构(比如列表、整数、字符串、整数列表,甚至另一个字典,或者字典的列表……你明白了吧)

1

要创建一个字典,你可以这样做:

censusvalues = {}
censusvalues['CA'] = {}
censusvalues['CA']['1960'] = <1960 census value>

你可以根据提取的数据来填充这个字典:

censusvalues['CA'] = {}
censusvalues['CA']['1960'] = 456
censusvalues['CA']['1970'] = 789
>>censusvalues
>>{'CA': {'1960': 456, '1970': 789}}

这个提示会要求用户输入州名和年份:

state = raw_input("Enter the state: ")
year = raw_input("Enter the year: ")

然后会做类似这样的事情:

 censusvalues[name][year] 

来打印输出结果。

我想在这里指出你代码中的一些问题(在做这些修改后,记得在开头导入re模块):

def main():
    data = open('database', 'r')
    lines = data.readlines()
    year = 0
    censusvalues = {}
    for line in lines:
        # Now do the line processing.
        # The first thing you need to do here is see which years 
        # you are about to grab data from.  To do this, you need to figure out
        # how to extract that from the file.  Every line that has a year in it is prefixed by the same number of spaces followed by a number, so you can get it that way:
        if re.match('<insert number of spaces here...too lazy to count>[0-9]', line):
            year = int(line[<number of spaces>:].strip())
            continue

        if line.startswith('      '):

        # Now process the state data
        <you need to insert code here to grab the state name>

            firsttotalpop = getsub(line, 42)
            secondtotalpop = getsub(line, 100)
            thirdtotalpop = getsub(line, 158)
            censusvalues[state][year] = firsttoalpop
            censusvalues[state][year-10] = secondtotalpop 
            censusvalues[state][year-20] = thirdtotalpop 
    return 0

最后,你需要考虑当一行中只有一个年份而不是三个年份时会发生什么。我把这个留给你自己去练习...

编辑:还有一件事,你还需要在尝试添加键值对之前检查字典是否存在...也许可以这样做:

if not <state> in censusvalues:
    censusvalues[<state>] = {}

撰写回答