加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 黄冈站长网 (http://www.0713zz.com/)- 数据应用、建站、人体识别、智能机器人、语音技术!
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

Python编程中3个常用的数据结构和算法

发布时间:2019-04-16 01:22:21 所属栏目:优化 来源:程序员爱学习
导读:副标题#e# Python内置了许多非常有用的数据结构,比如列表(list)、集合(set)以及字典(dictionary)。就绝大部分情况而言,我们可以直接使用这些数据结构。但是,通常我们还需要考虑比如搜索、排序、排列以及筛选等这一类常见的问题。 本篇文章将介绍3种常见

由*修饰的变量也可以位于列表的第一个位置。例如,比方说用一系列的值来代表公司过去8个季度的销售额。如果想对最近一个季度的销售额同前7个季度的平均值做比较,可以这么做:

  1. *trailing_qtrs, current_qtr = sales_record 
  2. trailing_avg = sum(trailing_qtrs) / len(trailing_qtrs) 
  3. return avg_comparison(trailing_avg, current_qtr) 

从Python解释器的角度来看,这个操作是这样的:

  1. >>> *trailing, current = [10, 8, 7, 1, 9, 5, 10, 3] 
  2. >>> trailing 
  3. [10, 8, 7, 1, 9, 5, 10] 
  4. >>> current 

(3) 讨论

对于分解未知或任意长度的可迭代对象,这种扩展的分解操作可谓是量身定做的工具。通常,这类可迭代对象中会有一些已知的组件或模式(例如,元素1之后的所有内容都是电话号码),利用*表达式分解可迭代对象使得开发者能够轻松利用这些模式,而不必在可迭代对象中做复杂花哨的操作才能得到相关的元素。

*式的语法在迭代一个变长的元组序列时尤其有用。例如,假设有一个带标记的元组序列:

  1. records = [ 
  2.  ('foo', 1, 2), 
  3.  ('bar', 'hello'), 
  4.  ('foo', 3, 4), 
  5. def do_foo(x, y): 
  6.  print('foo', x, y) 
  7. def do_bar(s): 
  8.  print('bar', s) 
  9. for tag, *args in records: 
  10.  if tag == 'foo': 
  11.  do_foo(*args) 
  12. elif tag == 'bar': 
  13.  do_bar(*args) 

当和某些特定的字符串处理操作相结合,比如做拆分(splitting)操作时,这种*式的语法所支持的分解操作也非常有用。例如:

  1. >>> line = 'nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false' 
  2. >>> uname, *fields, homedir, sh = line.split(':') 
  3. >>> uname 
  4. 'nobody' 
  5. >>> homedir 
  6. '/var/empty' 
  7. >>> sh 
  8. '/usr/bin/false' 
  9. >>> 

有时候可能想分解出某些值然后丢弃它们。在分解的时候,不能只是指定一个单独的*,但是可以使用几个常用来表示待丢弃值的变量名,比如_或者ign(ignored)。例如:

  1. >>> record = ('ACME', 50, 123.45, (12, 18, 2012)) 
  2. >>> name, *_, (*_, year) = record 
  3. >>> name 
  4. 'ACME' 
  5. >>> year 
  6. 2012 
  7. >>> 

*分解操作和各种函数式语言中的列表处理功能有着一定的相似性。例如,如果有一个列表,可以像下面这样轻松将其分解为头部和尾部:

  1. >>> items = [1, 10, 7, 4, 5, 9] 
  2. >>> head, *tail = items 
  3. >>> head 
  4. >>> tail 
  5. [10, 7, 4, 5, 9] 
  6. >>> 

在编写执行这类拆分功能的函数时,人们可以假设这是为了实现某种精巧的递归算法。例如:

  1. >>> def sum(items): 
  2. ... head, *tail = items 
  3. ... return head + sum(tail) if tail else head 
  4. ... 
  5. >>> sum(items) 
  6. 36 
  7. >>> 

但是请注意,递归真的不算是Python的强项,这是因为其内在的递归限制所致。因此,最后一个例子在实践中没太大的意义,只不过是一点学术上的好奇罢了。

3. 保存最后N个元素

(1) 问题

我们希望在迭代或是其他形式的处理过程中对最后几项记录做一个有限的历史记录统计。

(2) 解决方案

保存有限的历史记录可算是collections.deque的完美应用场景了。例如,下面的代码对一系列文本行做简单的文本匹配操作,当发现有匹配时就输出当前的匹配行以及最后检查过的N行文本。

  1. from collections import deque 
  2. def search(lines, pattern, history=5): 
  3.  previous_lines = deque(maxlen=history) 
  4.  for line in lines: 
  5.  if pattern in line: 
  6.  yield line, previous_lines 
  7.  previous_lines.append(line) 
  8. # Example use on a file 
  9. if __name__ == '__main__': 
  10.  with open('somefile.txt') as f: 
  11.  for line, prevlines in search(f, 'python', 5): 
  12.  for pline in prevlines: 
  13.  print(pline, end='') 
  14.  print(line, end='') 
  15.  print('-'*20) 

(3) 讨论

(编辑:PHP编程网 - 黄冈站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读