python内置的数据结构包括:列表(list)、集合(set)、字典(dictionary),一般情况下我们可以直接使用这些数据结构,但通常我们还需要考虑比如搜索、排序、排列以及赛选等一些常见的问题。

如何巧妙的使用数据结构和同数据有关的算法,在collections模块中包含了针对各种数据结构的解决方法。

1、序列分解为变量

  1. In [5]: a = (4,5,6)
  2. In [6]: x,y,z = a
  3. In [7]: x
  4. Out[7]: 4
  5. In [8]: z
  6. Out[8]: 6
  7. In [9]: y
  8. Out[9]: 5
  9. In [10]: b = ['python',222,(2018,9,30)] #嵌套分解变量
  10. In [11]: p,n,(year,mon,day) = b
  11. In [12]: p
  12. Out[12]: 'python'
  13. In [13]: n
  14. Out[13]: 222
  15. In [14]: year
  16. Out[14]: 2018
  17. In [15]: day
  18. Out[15]: 30
  19. #可以分解的对象只要是可迭代对象如字符串、文件、迭代器和生成器
  20. In [16]: s = 'py'
  21. In [17]: x,y = s
  22. In [18]: x
  23. Out[18]: 'p'
  24. #忽略某个值使用下划线代替
  25. In [19]: data = 'python'
  26. In [20]: x,_,_,y,_,_ = data
  27. In [21]: x
  28. Out[21]: 'p'
  29. In [22]: y
  30. Out[22]: 'h'

2、任意长度对象分解元素

要从某个可迭代对象中分解出N个元素,可以使用python的“*表达式”来代表多个

列1:在作业成绩中去掉最高和最低后取平均分

  1. In [47]: grades = (68,98,85,78,84,79,88)
  2. In [48]: def drop_first_last(grades):
  3. ...: first,*middle,last = grades
  4. ...: return sum(middle) / len(middle)
  5. ...:
  6. ...:
  7.  
  8. In [49]: drop_first_last(sorted(list(grades),reverse=True))
  9. Out[49]: 82.8

列2:在嵌套元组中*式语法的分解应用

  1. records = [
  2. ('foo',1,2,3),
  3. ('bar',11,22,33),
  4. ('foo',4,5,6),
  5. ('bar',44,55,66),
  6. ]
  7.  
  8. def do_foo(x,y,z):
  9. print('foo',x,y,z)
  10.  
  11. def do_bar(a,b,c):
  12. print('bar',a,b,c)
  13.  
  14. for tag,*args in records: #分解元组打印
  15. if tag == 'foo':
  16. do_foo(*args)
  17. elif tag == 'bar':
  18. do_bar(*args)
  19.  
  20. #outing
  21. foo 1 2 3
  22. bar 11 22 33
  23. foo 4 5 6
  24. bar 44 55 66

列3:通过split拆分分解元素

  1. In [52]: passwd = 'root:x:0:0:root:/root:/bin/bash'
  2.  
  3. In [53]: username,*_,homedir,sh = passwd.split(":")
  4.  
  5. In [54]: username
  6. Out[54]: 'root'
  7.  
  8. In [55]: homedir
  9. Out[55]: '/root'
  10.  
  11. In [56]: sh
  12. Out[56]: '/bin/bash'

3、保存最后N个元素

列1:使用collections.deque保存有限的历史纪录,deque用来创建一个固定长度的队列

  1. In [61]: from collections import deque
  2. #创建队列长度对象
  3. In [62]: q = deque(maxlen=3)
  4. #加入数据到队列
  5. In [63]: q.append(1)
  6.  
  7. In [64]: q.append(2)
  8.  
  9. In [65]: q.append(3)
  10.  
  11. In [66]: q
  12. Out[66]: deque([1, 2, 3])
  13.  
  14. In [67]: q.append(4)
  15.  
  16. In [68]: q
  17. Out[68]: deque([2, 3, 4])
  18. #从左边加入数据到队列
  19. In [69]: q.appendleft(5)
  20.  
  21. In [70]: q
  22. Out[70]: deque([5, 2, 3])
  23. #从末尾取出一个数据
  24. In [71]: q.pop()
  25. Out[71]: 3
  26.  
  27. In [72]: q
  28. Out[72]: deque([5, 2])
  29.  
  30. In [73]: q.popleft()
  31. Out[73]: 5
  32.  
  33. In [74]: q
  34. Out[74]: deque([2])

4、找到最大或最小的N个元素

在heapq模块中有两个函数nlargest()从最大的值开始取,nsmallest()从最小的值开始取

  1. In [75]: import heapq
  2.  
  3. In [76]: numbers = [1,3,4,9,11,34,55,232,445,9812,321,45,67,434,555]
  4. #取三个最大的值
  5. In [77]: heapq.nlargest(3,numbers)
  6. Out[77]: [9812, 555, 445]
  7. #取三个最小的值
  8. In [78]: heapq.nsmallest(3,numbers)
  9. Out[78]: [1, 3, 4]

5、python堆排序peapq模块

hepaq模块实现了python中的推排序,并提供了很多方法,让用python实现排序算法有了简单快捷的方式

  1. In [1]: import heapq
  2. In [2]: date = [19,1,9,3,11,21]
  3. In [3]: heap = []
  4. #heappush方法会插入一个元素到堆中,并按从小到大排序
  5. In [4]: for i in date:
  6. ...: heapq.heappush(heap,i)
  7. ...:
  8. In [5]: heap
  9. Out[5]: [1, 3, 9, 19, 11, 21]
  10. In [6]: date
  11. Out[6]: [19, 1, 9, 3, 11, 21]
  12. #heapify方法会重新排序整个列表
  13. In [7]: heapq.heapify(date)
  14. In [8]: date
  15. Out[8]: [1, 3, 9, 19, 11, 21]
  16. #heappop()方法会取出第一个元素,并将剩下的元素堆排序
  17. In [10]: date
  18. Out[10]: [19, 1, 9, 3, 11, 21]
  19. In [11]: heapq.heappop(date)
  20. Out[11]: 19
  21. In [12]: date
  22. Out[12]: [1, 3, 9, 21, 11]
  23. #heapreplace()的作用是在堆中取第一个元素并插入一个元素
  24. In [27]: date = [11,8,3,78,35]
  25. In [28]: heapq.heapreplace(date,1)
  26. Out[28]: 11
  27. In [29]: date
  28. Out[29]: [1, 8, 3, 78, 35]
  29. #在集合中找出最大或者最小的N个元素,可以使用nlargest()和nsmallest()
  30. In [30]: date = [3,88,32,97,56]
  31. In [31]: heapq.nlargest(2,date)
  32. Out[31]: [97, 88]
  33. In [33]: heapq.nsmallest(2,date)
  34. Out[33]: [3, 32]
  35. #nlargest()和nsmallest()还可以接受一个key参数来实现复杂的数据结构上的取值,如根据字典的值取值
  36. In [34]: port = [
  37. ...: {'name':'dhcp','port':67},
  38. ...: {'name':'mysql','port':3306},
  39. ...: {'name':'memcached','port':11211},
  40. ...: {'name':'nginx','port':80},
  41. ...: {'name':'ssh','port':22},]
  42.  
  43. In [35]: heapq.nlargest(3,port,key=lambda x:x['port'])
  44. Out[35]:
  45. [{'name': 'memcached', 'port': 11211},
  46. {'name': 'mysql', 'port': 3306},
  47. {'name': 'nginx', 'port': 80}]
  48.  
  49. In [36]: heapq.nsmallest(3,port,key=lambda x:x['port'])
  50. Out[36]:
  51. [{'name': 'ssh', 'port': 22},
  52. {'name': 'dhcp', 'port': 67},
  53. {'name': 'nginx', 'port': 80}]

实现优先级队列实例:

  1. import heapq
  2. class priorityqueue(object):
  3. def __init__(self):
  4. self._queue = []
  5. self._index = 0
  6. def push(self,item,priority):
  7. heapq.heappush(self._queue,(-priority,self._index,item))
  8. self._index += 1
  9. def pop(self):
  10. return heapq.heappop(self._queue)[-1]def listt(self):
  11. return self._queue
  12.  
  13. q = priorityqueue()
  14. q.push('python',44)
  15. q.push('java',2)
  16. q.push('c++',4)
  17. q.push('c#',8)
  18. q.push('goo',88)
  19. q.push('perl',1)
  20. date1 = q.listt()
  21. print(date1)
  22. print(q.pop())
  23. print(q.listt())
  24.  
  25. #output
  26. [(-88, 4, 'goo'), (-44, 0, 'python'), (-4, 2, 'c++'), (-2, 1, 'java'), (-8, 3, 'c#'), (-1, 5, 'perl')]
  27. goo
  28. [(-44, 0, 'python'), (-8, 3, 'c#'), (-4, 2, 'c++'), (-2, 1, 'java'), (-1, 5, 'perl')]

6、在字典中将键映射到多个值上

可以使用列表、元组、集合来创建多个值的字典键值

  1. dictlist = {
  2. 'a':[1,2],
  3. 'b':[3,4],
  4. 'c':[5,6],
  5. }
  6. dictset = {
  7. 'as':{7,8},
  8. 'bs':{9,0},
  9. }

在collection模块中的defaultdict类,它可以自动初始化第一个值,只需要添加元素即可

  1. In [1]: from collections import defaultdict
  2.  
  3. In [2]: d = defaultdict(list)
  4.  
  5. In [3]: d
  6. Out[3]: defaultdict(list, {})
  7.  
  8. In [4]: d['a'].append(1)
  9.  
  10. In [5]: d['a'].append(2)
  11.  
  12. In [6]: d
  13. Out[6]: defaultdict(list, {'a': [1, 2]})

7、让字典保持有序

要控制字典中元素的顺序,可以使用collections模块中的OrderedDict类,当对字典做迭代时,它会严格按照元素初始添加的顺序进行迭代

  1. from collections import OrderedDict
  2.  
  3. d = OrderedDict()
  4. d['one'] = 1
  5. d['two'] = 2
  6. d['three'] = 3
  7. d['four'] = 4
  8.  
  9. for key,value in d.items():
  10. print(key,value)
  11.  
  12. #output
  13. one 1
  14. two 2
  15. three 3
  16. four 4

当我们先精确控制字典中各字段的顺序然后序列化时,只需要在序列化前使用OrderdDist来构建字典数据,OrderedDict内部维护了一个双向链表,它会根据元素加入的顺序来排列键的位置,第一个新加入的元素被放置在链表的末尾,以后对已存在的键做修改也不会改变键的顺序,由于它额外创建了链表所占用的空间会是普通字典的2倍

  1. from collections import OrderedDict
  2. import json
  3. d = OrderedDict()
  4. d['one'] = 1
  5. d['two'] = 2
  6. d['three'] = 3
  7. d['four'] = 4
  8. jsd = json.dumps(d)
  9. d1 = json.loads(jsd)
  10. print(jsd)
  11. print(d1)
  12.  
  13. #
  14. {"one": 1, "two": 2, "three": 3, "four": 4}
  15. {'one': 1, 'two': 2, 'three': 3, 'four': 4}

8、字典中的计算(求最大值、最小值和排序)

  1. prices = {
  2. 'ACME':45.23,
  3. 'AAPL':612.78,
  4. 'IBM':205.55,
  5. 'HPQ':10.75,
  6. 'FB':10.75
  7. }
  8.  
  9. print(min(zip(prices.values(),prices.keys())))
  10. print(max(zip(prices.values(),prices.keys())))
  11. print(sorted(zip(prices.values(),prices.keys())))
  12.  
  13. #使用zip()将字典中的值映射为元组的迭代器,但zip()只能被使用一次
  14. #如果对比的值相同,则选择键的排序大小
  15. #
  16. (10.75, 'FB')
  17. (612.78, 'AAPL')
  18. [(10.75, 'FB'), (10.75, 'HPQ'), (45.23, 'ACME'), (205.55, 'IBM'), (612.78, 'AAPL')]

9、在两个字典中寻找相同点

  1. a = {'x':1,'y':2,'z':3}
  2. b = {'w':10,'x':11,'y':2}
  3. print(a.keys() & b.keys()) #a和b中同时都有的key
  4. print(a.keys() - b.keys()) #a中的键不在b中出现的key
  5. print(a.items() & b.items()) #a和b中键值都相同的元素
  6.  
  7. #
  8. {'x', 'y'}
  9. {'z'}
  10. {('y', 2)}
  1. In [1]: a = {'a':11,'b':22,'c':44,'d':99,'f':101}
  2. #推倒式排除键新建字典
  3. In [2]: c = {key:a[key] for key in a.keys() - {'b','d'}}
  4.  
  5. In [3]: c
  6. Out[3]: {'f': 101, 'a': 11, 'c': 44}

10、从序列中移除重复项并保持元素顺序

  1. dic = [{'x':1,'y':3},{'x':3,'y':8},{'x':1,'y':11},{'x':1,'y':3}]
  2. def dedupe(items,key=None):
  3. seen = set()
  4. for item in items:
  5. val = item if key is None else key(item)
  6. if val not in seen:
  7. yield item
  8. seen.add(val)
  9.  
  10. #key传递函数将序列中的元素转换为可哈希值,来去除重复项
  11. date = list(dedupe(dic,key=lambda d:(d['x'],d['y'])))
  12. print(date)
  13. date1 = list(dedupe(dic,key=lambda x:(x['x'])))
  14. print(date1)
  15.  
  16. #
  17. [{'x': 1, 'y': 3}, {'x': 3, 'y': 8}, {'x': 1, 'y': 11}]
  18. [{'x': 1, 'y': 3}, {'x': 3, 'y': 8}]

11、对切片命名

使用内置函数slice来创建切片对象

  1. In [4]: li = [1,2,3,4,5,6,7,8,9,0]
  2.  
  3. In [5]: cost = li[slice(2,8)]
  4.  
  5. In [6]: cost
  6. Out[6]: [3, 4, 5, 6, 7, 8]
  7.  
  8. In [8]: li[slice(2,9,2)]
  9. Out[8]: [3, 5, 7, 9]

12、找出序列中出现次数最多的元素

collections模块中的Counter类可以直接统计每个元素出现的次数,它会以字典的形式映射每个元素出现的次数,其中的most_common()方法可以直接显示结果,可传参数为显示的元素个数

  1. In [15]: date = [1,23,4,3,2,5,23,123,553,23,1,3,4,5,2,3,423,12,3,4,23,412,43]
  2.  
  3. In [16]: from collections import Counter
  4.  
  5. In [17]: Counter(date)
  6. Out[17]:
  7. Counter({1: 2,
  8. 23: 4,
  9. 4: 3,
  10. 3: 4,
  11. 2: 2,
  12. 5: 2,
  13. 123: 1,
  14. 553: 1,
  15. 423: 1,
  16. 12: 1,
  17. 412: 1,
  18. 43: 1})
  19. In [18]: Counter(date).most_common()
  20. Out[18]:
  21. [(23, 4),
  22. (3, 4),
  23. (4, 3),
  24. (1, 2),
  25. (2, 2),
  26. (5, 2),
  27. (123, 1),
  28. (553, 1),
  29. (423, 1),
  30. (12, 1),
  31. (412, 1),
  32. (43, 1)]
  33.  
  34. In [19]: Counter(date).most_common(2)
  35. Out[19]: [(23, 4), (3, 4)]
  36.  
  37. In [20]: Counter(date).most_common(4)
  38. Out[20]: [(23, 4), (3, 4), (4, 3), (1, 2)]
  1. In [27]: date1 = ['a','b','c','a','a','b']
  2.  
  3. In [28]: from collections import Counter
  4. #生成一个Counter对象,为字典映射的统计值
  5. In [29]: counts = Counter(date1)
  6.  
  7. In [30]: counts['a']
  8. Out[30]: 3
  9. #创建第二个序列
  10. In [31]: date2 = ['b','b','a']
  11. #先统计元素出现的次数
  12. In [32]: counts.most_common()
  13. Out[32]: [('a', 3), ('b', 2), ('c', 1)]
  14. #使用update()方法来手动更新counts对象
  15. In [33]: counts.update(date2)
  16. #查看结果
  17. In [34]: counts.most_common()
  18. Out[34]: [('a', 4), ('b', 4), ('c', 1)]
  19. #创建第二个counter对象
  20. In [35]: counts1 = Counter(date2)
  21. #counter对象可以用加减来运算
  22. In [36]: counts - counts1
  23. Out[36]: Counter({'a': 3, 'b': 2, 'c': 1})

13、字典列表排序

operator模块中的itemgetter函数可以对嵌套数据结构的排序会非常简单且运行很快

  1. from operator import itemgetter
  2. date1 = [
  3. {'fname':'Brian','lname':'Jones','uid':1003},
  4. {'fname':'David','lname':'Beazley','uid':1002},
  5. {'fname':'John','lname':'Cleese','uid':1001},
  6. {'fname':'Big','lname':'Jones','uid':1004},
  7. ]
  8.  
  9. print(sorted(date1,key=itemgetter('uid')))
  10. print(sorted(date1,key=itemgetter('uid'),reverse=True)) #反向排序
  11. print(sorted(date1,key=itemgetter('uid','fname'))) #通过多个公共键排序
  12.  
  13. print(sorted(date1,key=lambda x:x['uid'])) #也可以使用匿名函数来代替,但速度没有itemgetter()函数快
  14.  
  15. print(min(date1,key=itemgetter('uid'))) #itemgetter()也可以用在去最大或最小值上
  16. print(max(date1,key=itemgetter('uid')))
  17.  
  18. #
  19. [{'fname': 'John', 'lname': 'Cleese', 'uid': 1001}, {'fname': 'David', 'lname': 'Beazley', 'uid': 1002}, {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}, {'fname': 'Big', 'lname': 'Jones', 'uid': 1004}]
  20. [{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}, {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}, {'fname': 'David', 'lname': 'Beazley', 'uid': 1002}, {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}]
  21. [{'fname': 'John', 'lname': 'Cleese', 'uid': 1001}, {'fname': 'David', 'lname': 'Beazley', 'uid': 1002}, {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}, {'fname': 'Big', 'lname': 'Jones', 'uid': 1004}]
  22. [{'fname': 'John', 'lname': 'Cleese', 'uid': 1001}, {'fname': 'David', 'lname': 'Beazley', 'uid': 1002}, {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003}, {'fname': 'Big', 'lname': 'Jones', 'uid': 1004}]
  23. {'fname': 'John', 'lname': 'Cleese', 'uid': 1001}
  24. {'fname': 'Big', 'lname': 'Jones', 'uid': 1004}

对原生不支持比较操作的对象排序

  1. from operator import attrgetter
  2. class user(object):
  3. def __init__(self,user_id):
  4. self.user_id = user_id
  5. def __repr__(self):
  6. return 'user({})'.format(self.user_id)
  7. users = [user(11),user(22),user(3)]
  8. print(users)
  9. print(sorted(users,key=lambda x:x.user_id))
  10. print(sorted(users,key=attrgetter('user_id'))) #使用attrgetter()函数来对实例化对象的参数值排序

14、根据字段将记录分组

itertools模块中的函数groupby()可以通过扫描序列找出拥有相同值或是参数key指定的函数所返回的值的序列项,并将它们分组,groupby()创建一个迭代器,而每次迭代时都回返回一个值,和一个子迭代器,这个子迭代器可以产生所有在该分组内具有该值的项。

  1. from operator import itemgetter
  2. from itertools import groupby
  3. rows = [
  4. {'a':'python','date':'07/01/2012'},
  5. {'a':'java','date':'08/11/2015'},
  6. {'a':'c++','date':'09/12/2018'},
  7. {'a':'perl','date':'17/06/2017'},
  8. ]
  9. rows.sort(key=itemgetter('date'))
  10. print(rows)
  11. for date,items in groupby(rows,key=itemgetter('date')):
  12. print(date)
  13. for i in items:
  14. print(' ',i)
  15.  
  16. #
  17. [{'a': 'python', 'date': '07/01/2012'}, {'a': 'java', 'date': '08/11/2015'}, {'a': 'c++', 'date': '09/12/2018'}, {'a': 'perl', 'date': '17/06/2017'}]
  18. 07/01/2012
  19. {'a': 'python', 'date': '07/01/2012'}
  20. 08/11/2015
  21. {'a': 'java', 'date': '08/11/2015'}
  22. 09/12/2018
  23. {'a': 'c++', 'date': '09/12/2018'}
  24. 17/06/2017
  25. {'a': 'perl', 'date': '17/06/2017'}
  1. from collections import defaultdict
  2. #根据数据分组来构建一个一键多值的字典
  3. rows_date = defaultdict(list)
  4. for row in rows:
  5. rows_date[row['date']].append(row)
  6.  
  7. print(rows_date)
  8.  
  9. #
  10. defaultdict(<class 'list'>, {'07/01/2012': [{'a': 'python', 'date': '07/01/2012'}], '08/11/2015': [{'a': 'java', 'date': '08/11/2015'}], '09/12/2018': [{'a': 'c++', 'date': '09/12/2018'}], '17/06/2017': [{'a': 'perl', 'date': '17/06/2017'}]})

15、筛选序列中的元素

  1. #使用列表推到式来赛选列表中符合要求的值
  2. In [37]: mylist = [1,2,-5,10,-8,3,-1]
  3.  
  4. In [38]: list(i for i in mylist if i > 0)
  5. Out[38]: [1, 2, 10, 3]
  6.  
  7. In [39]: list(i for i in mylist if i < 0)
  8. Out[39]: [-5, -8, -1]
  9.  
  10. #如果输入的值非常多,可以先生成生成器然后筛选结果值
  11. In [43]: pos = (i for i in mylist if i > 0)
  12.  
  13. In [46]: for i in pos:
  14. ...: print(i)
  15. ...:
  16. 1
  17. 2
  18. 10
  19. 3

如果碰到筛选不标准的值如包含字符和数字,只筛选出数字呢?

  1. In [47]: values = [1,'','-4','-',88,'N/A','python','']
  2.  
  3. In [48]: def is_int(val):
  4. ...: try:
  5. ...: x = int(val)
  6. ...: return True
  7. ...: except ValueError:
  8. ...: return False
  9. ...:
  10. #在筛选不规则的值式使用函数来过滤异常然后使用filter函数处理
  11. In [49]: list(filter(is_int,values))
  12. Out[49]: [1, '', '-4', 88, '']
  13.  
  14. #用新值替换掉筛选不和规定的值
  15. In [50]: mylist = [1,4,-5,10,-7,2,3,-1]
  16.  
  17. In [51]: list(i if i > 0 else 0 for i in mylist)
  18. Out[51]: [1, 4, 0, 10, 0, 2, 3, 0]
  19.  
  20. In [52]: list(i if i < 0 else 0 for i in mylist)
  21. Out[52]: [0, 0, -5, 0, -7, 0, 0, -1]
  22.  
  23. #还可以使用itertools.compress()来构建一个布尔选择器序列来赛选数据
  24. In [53]: addresses = ['one','two','three','four','five']
  25.  
  26. In [54]: from itertools import compress
  27.  
  28. In [55]: counts = [1,3,5,6,3]
  29.  
  30. In [56]: more1 = [i > 3 for i in counts]
  31.  
  32. In [57]: more1
  33. Out[57]: [False, False, True, True, False]
  34.  
  35. In [58]: list(compress(addresses,more1))
  36. Out[58]: ['three', 'four']

16、从字典中提取子集

  1. prices = {
  2. 'ACME':45.23,
  3. 'AAPL':612.78,
  4. 'IBM':205.55,
  5. 'HPQ':37.20,
  6. 'FB':10.75,
  7. }
  8. #推到式创建值大于30的字典集合
  9. P1 = {key:value for key,value in prices.items() if value > 30}
  10. print(P1)
  11. #推倒式创建在tech中有的键的字典集合
  12. tech = {'ACME','IBM','HPQ','FB'}
  13. P2 = {key:value for key,value in prices.items() if key in tech}
  14. print(P2)
  15.  
  16. #
  17. {'ACME': 45.23, 'AAPL': 612.78, 'IBM': 205.55, 'HPQ': 37.2}
  18. {'ACME': 45.23, 'IBM': 205.55, 'HPQ': 37.2, 'FB': 10.75}
  1. #使用dict()函数来创建会更加清晰,效率会是上面的两倍
  2. P3 = dict((key,value) for key,value in prices.items() if value > 100)
  3. print(P3)
  4.  
  5. #
  6. {'AAPL': 612.78, 'IBM': 205.55}
  1. #多种实现方式,但这种方法会慢很多
  2. p4 ={key:prices[key] for key in prices.keys() & tech}
  3. print(p4)
  4.  
  5. #
  6. {'ACME': 45.23, 'IBM': 205.55, 'FB': 10.75, 'HPQ': 37.2}

17、将名称映射到序列的元素中

collections.namedtuple()模块定义命名元组

  1. In [1]: from collections import namedtuple
  2. In [2]: subject = namedtuple('subject',['one','two','three'])
  3. In [3]: sub = subject(1,2,3)
  4. In [4]: sub
  5. Out[4]: subject(one=1, two=2, three=3)
  6. In [7]: sub.index(2)
  7. Out[7]: 1
  8. In [9]: sub.one
  9. Out[9]: 1
  10. In [10]: sub.two
  11. Out[10]: 2
  12. In [11]: sub.three
  13. Out[11]: 3
  14. In [12]: len(sub)
  15. Out[12]: 3
  16. In [13]: a,b,c=sub
  17. In [14]: a
  18. Out[14]: 1
  19. In [15]: c
  20. Out[15]: 3
  1. #如果要修改某个值可以使用_replace()方法
  2. In [17]: sub._replace(one=88)
  3. Out[17]: subject(one=88, two=2, three=3)

18、同时对数据做转换和换算

  1. #使用生成器表达式将数据转换和换算
  2. In [19]: numbers = [1,2,3,4,5]
  3. In [20]: s = sum(x * x for x in numbers)
  4. In [21]: s
  5. Out[21]: 55
  6. In [26]: portfolio = [{'name':'GOOG','shares':50},{'name':'YHOO','shares':75},{'name':'AOL','shares':20},{'name':'SCOX','shares':65}]
  7. #对所有商品求和
  8. In [27]: sumnmber = sum(i['shares'] for i in portfolio)
  9. In [28]: sumnmber
  10. Out[28]: 210
  11. In [29]: minmber = min(i['shares'] for i in portfolio)
  12. In [30]: minmber
  13. Out[30]: 20
  14. In [31]: maxmber = max(i['shares'] for i in portfolio)
  15. In [32]: maxmber
  16. Out[32]: 75
  17. #也可以使用key参数来换算
  18. In [33]: min(portfolio,key=lambda s:s['shares'])
  19. Out[33]: {'name': 'AOL', 'shares': 20}

19、将多个映射合并为单个映射

  1. In [34]: a = {'x':11,'z':33}
  2.  
  3. In [35]: b = {'y':22,'z':44}
  4. #利用collections模块中的ChainMap类来实现多个字典的合并检查
  5. In [36]: from collections import ChainMap
  6. In [37]: c = ChainMap(a,b)
  7. In [38]: c
  8. Out[38]: ChainMap({'x': 11, 'z': 33}, {'y': 22, 'z': 44})
  9. In [39]: c['z'] = 33
  10. In [40]: c
  11. Out[40]: ChainMap({'x': 11, 'z': 33}, {'y': 22, 'z': 44})
  12. In [41]: c['z'] = 55
  13. In [42]: c
  14. Out[42]: ChainMap({'x': 11, 'z': 55}, {'y': 22, 'z': 44})
  15. In [43]: values = ChainMap()
  16. In [44]: values['x'] = 100
  17. In [45]: values = values.new_child()
  18. In [46]: values['x'] = 200
  19. In [47]: values
  20. Out[47]: ChainMap({'x': 200}, {'x': 100})
  21. In [48]: values = values.new_child()
  22. In [50]: values['x'] = 50
  23. In [51]: values
  24. Out[51]: ChainMap({'x': 50}, {'x': 200}, {'x': 100})
  25. In [52]: values['x']
  26. Out[52]: 50
  27.  
  28. #利用字典的update()方法将多个字典合并一起,它会重新构建一个完整的字典
  29. In [58]: a = {'x':1,'z':3}
  30. In [59]: b = {'y':2,'z':4}
  31. In [60]: merged = dict(b)
  32. In [61]: merged.update(a)
  33. In [62]: merged
  34. Out[62]: {'y': 2, 'z': 3, 'x': 1}
  35. #ChainMap使用的是原始的字典,对原始数据的更改会映射到新建的对象上
  36. In [63]: a = {'x':1,'z':3}
  37. In [64]: b = {'y':2,'z':4}
  38. In [65]: merged = ChainMap(a,b)
  39. In [66]: merged
  40. Out[66]: ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4})
  41. In [67]: merged['x']
  42. Out[67]: 1
  43. In [68]: a['x'] = 100
  44. In [69]: merged['x']
  45. Out[69]: 100
  46. In [70]: merged
  47. Out[70]: ChainMap({'x': 100, 'z': 3}, {'y': 2, 'z': 4})

python3数据结构与算法的更多相关文章

  1. Python3-Cookbook总结 - 第一章:数据结构和算法

    第一章:数据结构和算法 Python 提供了大量的内置数据结构,包括列表,集合以及字典.大多数情况下使用这些数据结构是很简单的. 但是,我们也会经常碰到到诸如查询,排序和过滤等等这些普遍存在的问题. ...

  2. 开启基本数据结构和算法之路--初识Graphviz

    在我的Linux刀耕开荒阶段,就想开始重拾C,利用C实现常用的基本数据结构和算法,而数据结构和算法的掌握的熟练程度正是程序的初学者与职业程序员的分水岭. 那么怎么开启这一段历程呢? 按照软件工程的思想 ...

  3. 【转】MySQL索引背后的数据结构及算法原理

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...

  4. [转]MySQL索引背后的数据结构及算法原理

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...

  5. MySQL索引背后的数据结构及算法原理【转】

    本文来自:张洋的MySQL索引背后的数据结构及算法原理 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持 ...

  6. 数据结构与算法JavaScript (一) 栈

    序 数据结构与算法JavaScript这本书算是讲解得比较浅显的,优点就是用javascript语言把常用的数据结构给描述了下,书中很多例子来源于常见的一些面试题目,算是与时俱进,业余看了下就顺便记录 ...

  7. 数据结构与算法 Big O 备忘录与现实

    不论今天的计算机技术变化,新技术的出现,所有都是来自数据结构与算法基础.我们需要温故而知新.        算法.架构.策略.机器学习之间的关系.在过往和技术人员交流时,很多人对算法和架构之间的关系感 ...

  8. 《java数据结构和算法》读书笔记

    大学时并不是读计算机专业的, 之前并没有看过数据结构和算法,这是我第一次看.         从数据结构方面来说:                数组:最简单,遍历.查找很快:但是大小固定,不利于扩展 ...

  9. MySQL索引背后的数据结构及算法原理

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...

随机推荐

  1. 【POI每日题解 #8】DYN-Dynamite

    你问蒟蒻为什么一天写两篇每日题解? 难道每日坚果你不能一天吃两包吗? 题目链接 哇…这道题第一反应就是二分答案[太明显了 枚举答案 就那个“关键节点到这些点中距离的最小值的最大值”[蒟蒻读了好几遍…… ...

  2. 自学Zabbix3.12.4-动作Action-Operation配置

    点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 3.12.4 自学Zabbix3.12.4-动作Action-Operation配置 1. 概述 ...

  3. 学习Spring Boot:(二十四)多数据源配置与使用

    前言 随着业务量增大,可能有些业务不是放在同一个数据库中,所以系统有需求使用多个数据库完成业务需求,我们需要配置多个数据源,从而进行操作不同数据库中数据. 正文 JdbcTemplate 多数据源 配 ...

  4. Dominator Tree & Lengauer-Tarjan Algorithm

    问题描述 给出一张有向图,可能存在环,对于所有的i,求出从1号点到i点的所有路径上的必经点集合. 什么是支配树 两个简单的小性质—— 1.如果i是j的必经点,而j又是k的必经点,则i也是k的必经点. ...

  5. oh-my-zsh的安装与基本配置

    1. 准备工作 安装需要用到:wget curl git zsh 官网:http://ohmyz.sh/ GitHub主页:https://github.com/robbyrussell/oh-my- ...

  6. [NOI2017]泳池——概率DP+线性递推

    [NOI2017]泳池 实在没有思路啊~~~ luogu题解 1.差分,转化成至多k的概率减去至多k-1的概率.这样就不用记录“有没有出现k”这个信息了 2.n是1e9,感觉要递推然后利用数列的加速技 ...

  7. 洛谷P4145 上帝造题的⑦minutes ②

    又是线段树. 区间开平方求和,套路题. 如果开到了1就不用再开下去了,否则直接到底. 记得 l > r 时交换 l r #include <cstdio> #include < ...

  8. 路径或文件名中含有中文的jar文件双击启动不了 -> Java7的Bug?

    至从安装了java7后,才发现部分可执行的jar文件双击都启动不了了. 比如所有的jar文件放在桌面上双击启动不了. 比如所有的文件名中含有中文的jar文件双击启动不了. 比如一个 abc.jar 放 ...

  9. 初探react(一)

    我们学习react首先是要了解react是什么,以及他的特点. React 是一个用于构建用户界面的 JAVASCRIPT 库,起源于 Facebook 的内部项目,用来架设 Instagram 的网 ...

  10. #define 多行多语句

    #define DEBUG_ENABLE 1 #if DEBUG_ENABLE > 0 #define DEBUG_PORT UART_PORT2 #define DBG_BUF_LEN 512 ...