【问题标题】:Python help - dictionaries, keys, valuesPython 帮助 - 字典、键、值
【发布时间】:2014-04-09 18:33:15
【问题描述】:

我正在尝试编写一个程序,但遇到了很多麻烦。这是我的指示: 对于这个程序,您将从一些美国人口普查数据创建一个简单的数据库。该数据库将包含一个字典,其键是州名,其值是从 1900 年到 1990 年每一年的人口列表。创建数据库后,您将编写一个简单的命令驱动程序,该程序将提示用户输入州名和年份,然后报告该州该年的人口。您的程序将执行此操作,直到用户键入任何以“q”或“Q”开头的单词。

人口普查数据在这里:http://www.census.gov/population/www/censusdata/files/urpop0090.txt 我已将所有内容保存到一个名为“数据库”的平面 ascii 文件中

花一些时间研究文件。它包含一些多余的信息(至少出于我们的目的)。您需要制定一种策略,从文件中准确提取您需要的信息以放入数据库(字典)中。

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

  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

我在弄清楚如何实际创建带有键/值的字典,以及如何让人口值与州名的键保持一致时遇到了一些麻烦。另外,我不肯定如何接受用户输入并将其用作键。我也不确定上面的代码是否正确获取州名称和人口信息。

任何建议/帮助将不胜感激!

【问题讨论】:

  • 您的问题到底是什么?即,您在哪里遇到了麻烦。感谢您的编辑,请稍等。
  • 修复已发布代码的缩进也会有所帮助。
  • wat...lol 编辑怎么了。

标签: python dictionary key readlines


【解决方案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

最后,您需要考虑当您在一行中只有一年而不是 3 年时会发生什么。我将把它作为练习留给您...

编辑:还有一件事,在尝试向其添加 K/V 对之前,您还需要检查字典是否存在......可能是这样的:

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

【讨论】:

  • 好吧,关键是您可以通过编程方式执行此操作...例如,您只需要创建一次 censusvalue 字典和一次 censusvalues['CA'] 字典。在为每个状态创建空 dict 后,您可以像我在上面所做的那样分配键值对,但您会将其包装在一些读取数据的 for 循环中。此外,要获取用户输入,您可以执行 state = raw_input("Enter the state: ") year = raw_input("Enter the year: ") 之类的操作
  • 您可以创建一个以编程方式执行此操作的函数,这是我的观点。我将编辑您的代码以向您展示我的意思。
  • 我在上面 nwalshes 的回答中回答了这个问题。
【解决方案2】:

就创建字典而言:

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 其中键可以是整数或字符串(在您的情况下为字符串),值几乎可以是任何数据结构(列表、整数、字符串、整数列表,甚至另一个 dict,或 dicts 列表.. 你得到图片)

【讨论】:

  • @thunder1417 您制作了一个程序,因此您不必为每个州和每个人口都这样做。制作一个字符串以获取州名并制作整数以获取人口。然后制作一个以州名称为键的字典并将其设置为人口。您需要将字典的更新放在读取州名称和人口的循环中。
  • @thunder1417 我认为您对自己的模式考虑得太多了,但是您了解了一般概念并且使它们变得比必须的更困难。例如,以获取第一人口为例。通过查看文本文件,您知道它将从第 34 个字符开始。你知道它会在 44 结束。因此,人口是 34 和 44 之间的字符串。现在只需使用字符串方法删除逗号。这比从后面开始并向前移动并替换逗号要简单得多。
  • @thunder1417 我会发布一个答案来解释它。
【解决方案3】:

鉴于:我们知道人口 1 从字符 34 开始,因为没有一个州的人口超过 1 亿。我们知道人口 1 将在字符 44 结束。

但是,有些州的人口少于一千万,因此它们必须从字符 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 

那么对于人口二和人口三,您只需更改状态信息的索引并使用上述相同的逻辑。

这一切都可以在一行中完成:

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

【讨论】:

  • 我似乎无法正确格式化代码,所以我将发布我的一个班轮作为对您代码的编辑。
  • 要将状态名称用作键,您需要从文件中获取它们。由于您知道每个州名的行都以 6 个空格开头,因此您可以在该行上执行以下操作:state = line[6:].split(' ')[0]
  • @deweyredman 这不适用于名称中有空格的州​​。比如南达科他州。但只需在拆分中添加另一个空格即可解决该问题。
  • 好收获。我需要回去工作,但我认为你们已经足够了。
  • 与我们为人口所做的非常相似的事情应该可以工作(将文本从字符 6 抓取到...随便...,然后从中删除空格)
猜你喜欢
  • 1970-01-01
  • 2010-11-14
  • 2015-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-17
  • 1970-01-01
  • 2021-02-08
相关资源
最近更新 更多