Python Dict 和文件

字典哈希表

Python 的高效键值对哈希表结构称为“字典”。字典的内容可以写为大括号 { } 中的一系列键值对,例如 dict = {key1:value1, key2:value2, ... }。所谓“空字典”只是一对空大括号 {}。

在字典中查找或设置值时,需要使用方括号,例如 dict['foo'] 会查找键“foo”下的值。字符串、数字和元组用作键,任何类型都可以是值。其他类型可能会或不能作为键正确运行(字符串和元组是不可变的,因此能够正常发挥作用)。查找不在字典中的值会抛出 KeyError 错误 - 请使用“in”检查键是否存在于字典中,或使用 dict.get(key),它会返回相应值,如果键不存在,则返回 None(或者,使用 get(key, not-found) 可指定在键不存在的情况下返回什么值)。

  ## Can build up a dict by starting with the empty dict {}
  ## and storing key/value pairs into the dict like this:
  ## dict[key] = value-for-that-key
  dict = {}
  dict['a'] = 'alpha'
  dict['g'] = 'gamma'
  dict['o'] = 'omega'

  print(dict) ## {'a': 'alpha', 'o': 'omega', 'g': 'gamma'}

  print(dict['a'])     ## Simple lookup, returns 'alpha'
  dict['a'] = 6       ## Put new key/value into dict
  'a' in dict         ## True
  ## print(dict['z'])                  ## Throws KeyError
  if 'z' in dict: print(dict['z'])     ## Avoid KeyError
  print(dict.get('z'))  ## None (instead of KeyError)

键为“a”“o”“g”的字典

默认情况下,字典上的 for 循环会迭代其键。按键将以任意顺序显示。方法 dict.keys() 和 dict.values() 会明确返回键或值的列表。还有一个 items() 方法,用于返回一个包含 (key, value) 元组的列表,这是检查字典中的所有键值数据的最有效方法。所有这些列表都可以传递给 sort() 函数。

  ## By default, iterating over a dict iterates over its keys.
  ## Note that the keys are in a random order.
  for key in dict:
    print(key)
  ## prints a g o

  ## Exactly the same as above
  for key in dict.keys():
    print(key)

  ## Get the .keys() list:
  print(dict.keys())  ## dict_keys(['a', 'o', 'g'])

  ## Likewise, there's a .values() list of values
  print(dict.values())  ## dict_values(['alpha', 'omega', 'gamma'])

  ## Common case -- loop over the keys in sorted order,
  ## accessing each key/value
  for key in sorted(dict.keys()):
    print(key, dict[key])

  ## .items() is the dict expressed as (key, value) tuples
  print(dict.items())  ##  dict_items([('a', 'alpha'), ('o', 'omega'), ('g', 'gamma')])

  ## This loop syntax accesses the whole dict by looping
  ## over the .items() tuple list, accessing one (key, value)
  ## pair on each iteration.
  for k, v in dict.items(): print(k, '>', v)
  ## a > alpha    o > omega     g > gamma

策略说明:从性能角度来看,字典是您最有用的工具之一,您应尽可能使用它来轻松整理数据。例如,您可以读取一个日志文件,其中每行都以 IP 地址开头,并使用 IP 地址作为键,将数据存储到字典中,并将 IP 地址出现的行列表作为值。读取整个文件后,您可以查询任何 IP 地址,并立即查看其行列表。字典接受分散的数据,并将其转换为连贯的内容。

字典格式

% 运算符可方便地按名称将字典中的值替换为字符串:

  h = {}
  h['word'] = 'garfield'
  h['count'] = 42
  s = 'I want %(count)d copies of %(word)s' % h  # %d for int, %s for string
  # 'I want 42 copies of garfield'

  # You can also use str.format().
  s = 'I want {count:d} copies of {word}'.format(h)

Del

“del”运算符用于执行删除操作。在最简单的情况下,它可以移除变量的定义,就好像该变量尚未定义一样。Del 还可用于列表元素或 slice,以删除列表的该部分以及从字典中删除条目。

  var = 6
  del var  # var no more!

  list = ['a', 'b', 'c', 'd']
  del list[0]     ## Delete first element
  del list[-2:]   ## Delete last two elements
  print(list)      ## ['b']

  dict = {'a':1, 'b':2, 'c':3}
  del dict['b']   ## Delete 'b' entry
  print(dict)      ## {'a':1, 'c':3}

文件

open() 函数会打开并返回一个文件句柄,该句柄可用于以常规方式读取或写入文件。代码 f = open('name', 'r') 会将文件打开到变量 f,以便进行读取操作,并在完成后使用 f.close()。如需写入,请使用“w”而非“r”,如需附加,请使用“a”。标准的 for 循环适用于文本文件,用于遍历文件的行(仅适用于文本文件,不适用于二进制文件)。for 循环是一种简单而高效的方式,可用于查看文本文件中的所有行:

  # Echo the contents of a text file
  f = open('foo.txt', 'rt', encoding='utf-8')
  for line in f:   ## iterates over the lines of the file
    print(line, end='')    ## end='' so print does not add an end-of-line char
                           ## since 'line' already includes the end-of-line.
  f.close()

一次阅读一行具有很棒的品质,并不是所有文件都需要同时在内存中放好;如果您希望查看 10 GB 文件中的每一行,而不使用 10 GB 内存,这会非常方便。f.readlines() 方法会将整个文件读取到内存中,并将其内容作为行列表返回。f.read() 方法会将整个文件读取到单个字符串中,这是一种方便的方式,可一次性处理文本,例如使用正则表达式(稍后会介绍)。

对于写入操作,将数据写入打开的输出文件的最简单方法是使用 f.write(string) 方法。或者,您也可以将“print”与打开的文件搭配使用,例如“print(string, file=f)”。

文件 Unicode

如需读取和写入 Unicode 编码的文件,请使用 `'t'` 模式并明确指定编码:


with open('foo.txt', 'rt', encoding='utf-8') as f:
  for line in f:
    # here line is a *unicode* string

with open('write_test', encoding='utf-8', mode='wt') as f:
    f.write('\u20ACunicode\u20AC\n') #  €unicode€
    # AKA print('\u20ACunicode\u20AC', file=f)  ## which auto-adds end='\n'

练习增量开发

要构建 Python 程序,不要一步到位,请仅确定第一个里程碑,例如“第一步是提取字词列表”。编写代码以达到该里程碑,然后只需在该时间点输出数据结构,然后您可以执行 sys.exit(0),以便程序不会提前运行到未完成的部分。当里程碑代码正常运行后,您就可以开始编写下一个里程碑的代码了。能够查看某个状态下变量的输出内容有助于您思考如何转换这些变量以进入下一个状态。采用这种模式,Python 的速度非常快,您只需进行一些小更改并运行程序,即可了解其运作方式。利用快速周转时间,通过简单的步骤构建您的计划。

练习:wordcount.py

结合使用所有基本 Python 内容(字符串、列表、字典、元组、文件),尝试完成基本练习中的摘要 wordcount.py 练习。