#! /usr/bin/env python
# -*- coding: utf-8 -*-
# 1.1.2
# 将元组或序列分解为单独变量
# p=(4,5)
# x,y=p
# print(x)
# print(y)
# date=['AMCE',50,91.1,(2012,12,21)]
# # name,shares,price,date= date
# # print(date)
# name,shares,price,(year,mon,day) = date
# print(day)
# 1.1.3
# 只要对象时可迭代的,都可以分解。
# s = 'Hello'
# a,b,c,d,e=s
# print(e)
# 1.2.2
# *表达式 分解不定长可迭代对象
# record = ('Dave','dave@example.com','773-555-1212','847-55-1212')
# name,email,*phone_numbers=record #p3错误
# print(phone_numbers)
# 1.2.3
# records=[
# ('foo',1,2),
# ('bar','hello'),
# ('foo',3,4),
# ]
# def do_foo(x,y):
# print('foo',x,y)
# def do_bar(s):
# print('bar',s)
# for tag,*args in records:
# if tag =='foo':
# do_foo(*args)
# elif tag =='bar':
# do_bar(*args)
# line ='nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false'
# uname,*fields,homedir,sh =line.split(':')
# print(homedir)
# print(fields)
# _ 或ign(ignored)丢弃不需要的值
# record= ('ACME',50,123.45,(12,18,2012))
# name ,*_,(*_,year)=record
# print(name)
# print(year)
# items = [1,10,7,4,5,9]
# head,*tail =items
# print(head)
# print(tail)
# def sum(items):
# head,*tail=items
# return head + sum(tail) if tail else head
#
# print(sum(items))
# 1.3.2
# from collections import deque
# def search(lines,pattern,history=5):
# previous_lines =deque(maxlen=history)
# for line in lines:
# yield line,previous_lines
# previous_lines.append(line)
# if __name__ == '__main__':
# with open('somefile.txt') as f:
# for line ,prevlines in search(f,'python',5):
# for pline in prevlines:
# print(pline,end='')
# print('-'*20)
# 1.3.3
from collections import deque
# q=deque(maxlen=3)
# q.append(1)
# q.append(2)
# q.append(3)
# print(q)
# q.append(4)
# print(q)
# q.append(5)
# print(q)
# 双端队列: 简单队列,如果不知道最大长度,则无界限,可以在两端执行添加和弹出。
# q = deque()
# q.append(1)
# q.append(2)
# q.append(3)
# print(q)
# q.appendleft(4)
# print(q)
# print(q.pop())
# print(q)
# print(q.popleft())
# 从队列两端增删元素复杂度都是O(1).而从列表头部插入或移除时复杂度为O(N)
# 1.4.2从集合中找出N个最大或最小值
import heapq
# nums = [1,8,2,23,7,-4,18,23,42,37,2]
# print(heapq.nlargest(3,nums))
# print(heapq.nsmallest(3,nums))
# 两个函数都可以接受一个参数key
# portfolio =[
# {'name':'IBM','shares':100,'price':91.1},
# {'name':'AAPL','shares':50,'price':543.22},
# {'name':'FB','shares':200,'price':21.09},
# {'name':'HPQ','shares':35,'price':31.75},
# {'name':'YHOO','shares':45,'price':16.35},
# {'name':'ACME','shares':75,'price':115.65},
# ]
# cheap = heapq.nsmallest(3,portfolio,key=lambda s:s['price'])
# expensive = heapq.nlargest(3,portfolio,key=lambda s:s['price'])
# print(cheap)
# print(expensive)
# 1.4.3
# nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
# heap =list(nums)
# heapq.heapify(heap)
# print(heap)
# print(heapq.heappop(heap))
# print(heapq.heappop(heap))
# print(heapq.heappop(heap))
# print(heapq.heappop(heap))
# print(heapq.heappop(heap))
# print(heapq.heappop(heap))
# print(heapq.heappop(heap))
# 堆最重要的特性是heap[0]总是最小的元素。heapq.heappop()弹出最小的元素,次小的放到第一位。
# 要找的元素相对少时可以用nlargest()和nsmallest();就找一个可以用min(),max();找的多时用排序切片sorted(items)[:N]/sorted(items)[-N:]
# 1.5
# 1.6.2
# 一键多值字典【multidict】
# from collections import defaultdict
# d = defaultdict(list)
# d['a'].append(1)
# d['a'].append(2)
# d['b'].append(4)
# print(d)
# d=defaultdict(set)
# d['a'].add(1)
# d['a'].add(2)
# d['b'].add(4)
# print(d)
# 1.7.2
# 迭代时严格按照初始添加顺序
# from collections import OrderedDict
# d =OrderedDict()
# d['foo'] =1
# d['bar'] =2
# d['spam']=3
# d['grok']=4
# for key in d:
# print(key,d[key])
# 1.8.2
# prices = {
# 'ACME':45.23,
# 'AAPL':612.78,
# 'IBM':205.55,
# 'HPQ':37.20,
# 'FB':10.75
# }
#
# min_price =min(zip(prices.values(),prices.keys())) #zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
# print(min_price)
# prices_sorted = sorted(zip(prices.values(),prices.keys()))
# print(prices_sorted)
# 1.9.2
# a = {
# 'x':1,
# 'y':2,
# 'z':3
# }
# b={
# 'w':10,
# 'x':11,
# 'y':2
# }
#
# c = a.keys() & b.keys()
# print(c)
# c = a.keys() -b.keys()
# print(c)
# c=a.items() & b.items()
# print(c)
# 1.10.2
#序列去重且顺序不变
# def dedupe(items):
# seen =set()
# for item in items:
# if item not in seen:
# yield item
# seen.add(item)
#
# #如果序列中的元素不可哈希(可哈希:整数、浮点数、字符串、元组)
# def dequpe(items,key=None):
# seen = set()
# for item in items:
# val = item if key is None else key(item)
# if val not in seen:
# yield item
# seen.add(val)
# 1.11.3切片命名
# items =[0,1,2,3,4,5,6]
# a = slice(2,4)
# print(items[2:4])
# print(items[a])
# items[a] = [10,11]
# print(items)
# del items[a]
# print(items)
# 1.12.2
# words=[
# 'look','into','my','eyes','look','into','my','eyes',
# 'the','eyes','the','eyes','the','eyes','not','around','the',
# 'eyes',"don't",'look','around','the','eyes','look','into',
# 'my','eyes',"you're",'under'
# ]
# from collections import Counter
# # word_counts =Counter(words)
# # top_three = word_counts.most_common(3)
# # print(top_three)
# # print(word_counts['not'])
# morewords = ['why','are','you','not','looking','in','my','eyes']
# # # for word in morewords:
# # # word_counts[word] +=1
# # word_counts.update(morewords)
# # print(word_counts['eyes'])
# 可以进行加减运算
# a = Counter(words)
# b=Counter(morewords)
# print(a)
# print(b)
# c = a + b
# print(c)
# d=a-b
# print(d)
# 1.13.2通过公共键对字典列表排序
# rows= [
# {'fname':'Brian','lname':'Jones','uid':1003},
# {'fname':'David','lname':'Beazley','uid':1002},
# {'fname':'John','lname':'Cleese','uid':1001},
# {'fname':'Big','lname':'Jones','uid':1004},
# ]
from operator import itemgetter
# rows_by_fname =sorted(rows,key=itemgetter('fname'))
# rows_by_uid =sorted(rows,key=itemgetter('uid'))
# print(rows_by_fname)
# print(rows_by_uid)
#多键
# rows_by_lfname = sorted(rows,key=itemgetter('lname','fname'))
# print(rows_by_lfname)
#
# #lambda表达式,在性能上不够快
# rows_by_fname_l =sorted(rows,key=lambda r:r['fname'])
# print(rows_by_fname_l)
# #同样用于Min和max
# print(min(rows,key=itemgetter('uid')))
# 1.14.2
# class User:
# def __init__(self,user_id):
# self.user_id=user_id
# def __repr__(self):
# return 'User({})'.format(self.user_id)
#
# users = [User(23),User(3),User(99)]
# # print(sorted(users,key=lambda u:u.user_id))
# from operator import attrgetter
# print(sorted(users,key=attrgetter('user_id')))
# 同样适用于min和max。性能上后者比前者快
# 1.15.2根据字段分组
# rows = [
# {'address':'5412 N CLARK','date':'07/01/2012'},
# {'address':'5148 N CLARK','date':'07/04/2012'},
# {'address':'5800 E 58TH','date':'07/02/2012'},
# {'address':'2122 N CLARK','date':'07/03/2012'},
# {'address':'5645 N RAVENSWOOD','date':'07/02/2012'},
# {'address':'1060 W ADDISON','date':'07/02/2012'},
# {'address':'4801 N BROADWAY','date':'07/01/2012'},
# {'address':'1039 W GRANVILLE','date':'07/04/2012'},
# ]
# from operator import itemgetter
# from itertools import groupby
# rows.sort(key=itemgetter('date'))
# for date,items in groupby(rows,key=itemgetter('date')):
# print(date)
# for i in items:
# print('',i)
#
# from collections import defaultdict
# rows_by_date = defaultdict(list)
# for row in rows:
# rows_by_date[row['date']].append(row)
#
# for r in rows_by_date['07/01/2012']:
# print(r)
# 1.16.2 列表推导式
# mylist= [1,4,-5,10,-7,2,3,-1]
# myl = [n for n in mylist if n>0]
# print(myl)
# #如果原列表数据庞大,则结果也庞大。使用生成器表达式来优化
# pos = (n for n in mylist if n>0)
# print(pos)
# values = ['1','2','-3','-','4','N/A','5']
# def is_int(val):
# try:
# x = int(val)
# return True
# except ValueError:
# return False
#
# ivals = list(filter(is_int,values))
# #filter创建了一个生成器
# print(ivals)
# 1.16.3
# addresses=[
# '5412 N CLARK',
# '5148 N CLARK',
# '5800 E 58TH',
# '2122 N CLARK',
# '5645 N RAVENSWOOD',
# '1060 W ADDISON',
# '4801 N BROADWAY',
# '1039 W GRANVILLE',
# ]
# counts = [0,3,10,4,1,7,6,1]
# from itertools import compress
# more5=[n>5 for n in counts]
# l1 = list(compress(addresses,more5)) #compress返回一个迭代器
# print(l1) #p29答案有误
# 1.17.2字典推导式
# prices = {
# 'ACME':45.23,
# 'AAPL':612.78,
# 'IBM':205.55,
# 'HPQ':37.20,
# 'FB':10.75
# }
# p1 = { key:value for key,value in prices.items() if value>200}
# print(p1)
#
# tech_names = { 'AAPL','IBM','HPQ','MSFT'}
# p2 = { key:value for key,value in prices.items() if key in tech_names}
# print(p2)
# 1.20.3将多个映射合并为单个映射
a = {'x':1,'z':3}
b = {'y':2,'z':4}
from collections import ChainMap
c = ChainMap(a,b)
print(c)
print(len(c))
print(list(c.keys()))
print((list(c.values())))
c['z']=10
print(a)
del c['x']
print(a)
#修改映射会作用到第一个结构;ChainMap使用的是原始字典,且不会增加内存