<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 1.17 从字典中提取子集
有构造的字典 他是另外一个字典的子集
最简单使用 字典推导
通过创建一个元组序列 后将之传至dict()func 实现
Step1:  大多数情况下 字典推导能做到的，可通过创建一个元组sequence 然后将之传至 dict() func 也可
Step2:  but 字典推导表达意思更加清晰 同时 运行速度更快(近一倍)<br>同时 第二个例子程序 可重写
Step3:  上述两行推导 -- '&' 与 'and' 区别：
一个是位运算
    num1 &amp; num2 等同于 bin(num1) &amp; bin(num2)
一个是逻辑运算
    num1 and num2 &lt;&lt;if num1 is False =&gt; False, else =&gt; num2&gt;&gt;[and 与 只要有一个假即假]
在这里 & 的作用是 匹配 prices.keys() 与 tech_names 中 所含元素 相匹配的
结合以下描述,虽然 prices.keys() tech_names 两者类型but
Step4:  1.18 映射名称到序列元素
将下标访问的 list or tuple 中的元素<br>想转化成通过名称访问的元素
利用collections.nameetuple() func 来使用一个普通的tuple帮助 解决。<br>实际上 一个返回python 中标准tuple 类型的子类的工厂方法Factory Method<br>需传递一个类型名与所需字段 后其返回一个类 and  你可以初始化 此类 and 为你定义的字段传递值
Step5:  nametuple 实例 看起来像 一个普通的类实例 and 其跟元组类型 可交换 and 支持所有普通元组操作 如 索引 and 解压
Step6:  namedtuple 's 主要用途 即 将你的代码从下标 操作解脱出来  and if 从数据库中调用中返回了很大的元组列表 and 通过通过 下标 去操作其中元素 但你 当表中添加了新的列的时候 你的代码就会出错 if 使用 namedtuple 即不会
使用普通 tuple 的代码
Step7:  下标操作通常会让代码表意不明 并且非常依赖记录records 的结构<br>if 出现 歧义
Step8:  namedtuple 另一个用途 是作为dict 的替代 because dict 存储需要更多的内存空间 and 需要构建一个非常大的包含字典的数据结构 and 使用命名元组会更加高效 BUT 不像dict 一个namedtuple 是不可更改
Step9:  以上不能使用  s.shares = 98<br> if want to change the attr 可以使用namedtuple instance 's _replace() and 其会创建一个全新的namedtuple and 将对应字段用新的值取代
Step10:  _replace() method and 有用特性 is 当你namedtuple 拥有可选或缺失字段时， 他是个超级方便填充数据的方法 可以先创建一个内含默认值 的原型(初态)tuple and 使用_replace() 创建新值被更新过的instance
Step11:  if you目标是一个需要更新很多instance's attr 高效的数据结构 BUT namedtuple is not 最佳选择 YOU can 使用一个包含 _slots_ method 的类<br>REF
Step12:  上述是将 生成器表达式 作为一个单独 argument 传递给func 时候 的巧妙语法 (不需要多加一个括号) 加不加括号 两者等效
Step13:  使用一个生成器表达式作为 argument 会比先创建一个临时列表更加高效 and 优雅
Step14:  以上多创建临时列表 速度会变慢 即将会创建一个巨大的仅仅被使用一次就被丢弃的临时数据结构!!!!!!
<ASSISTANT_TASK:>
Python Code:
prices = {
    'ACME': 45.23,
    'AAPL': 612.78,
    'IBM': 205.55,
    'HPQ': 37.20,
    'FB': 10.75
}
# Make a dictionary of all prices over 200
p1 = {key: value for key, value in prices.items() if value > 200}
# Make a dictionary of tech stocks
tech_names = {'AAPL', 'IBM', 'HPQ', 'MSFT'}
p2 = {key: value for key, value in prices.items() if key in tech_names}
print(p1,'\n',p2)
Explanation: 1.17 从字典中提取子集
有构造的字典 他是另外一个字典的子集
最简单使用 字典推导
通过创建一个元组序列 后将之传至dict()func 实现
End of explanation
p3 = dict((key, value) for key, value in prices.items() if value > 200)
print(p3)
Explanation: 大多数情况下 字典推导能做到的，可通过创建一个元组sequence 然后将之传至 dict() func 也可
End of explanation
# Make a dictionary of tech stocks
tech_names = {'AAPL', 'IBM', 'HPQ', 'MSFT'}
p4 = {key: prices[key] for key in prices.keys() & tech_names}
print(p4)
# p4 = {key: prices[key] for key in prices.keys() and tech_names}
Explanation: but 字典推导表达意思更加清晰 同时 运行速度更快(近一倍)<br>同时 第二个例子程序 可重写
End of explanation
prices.keys()
tech_names
type(prices.keys()) == type(tech_names)
prices.keys() & tech_names
type(prices.keys() & tech_names)
Explanation: 上述两行推导 -- '&' 与 'and' 区别：
一个是位运算
    num1 &amp; num2 等同于 bin(num1) &amp; bin(num2)
一个是逻辑运算
    num1 and num2 &lt;&lt;if num1 is False =&gt; False, else =&gt; num2&gt;&gt;[and 与 只要有一个假即假]
在这里 & 的作用是 匹配 prices.keys() 与 tech_names 中 所含元素 相匹配的
结合以下描述,虽然 prices.keys() tech_names 两者类型but
End of explanation
from collections import namedtuple
Subsciber = namedtuple('Subscriber',['addr','joined'])
sub = Subsciber('jonesy@exit.com','2012-10-19')
sub
sub.addr
sub.joined
Explanation: 1.18 映射名称到序列元素
将下标访问的 list or tuple 中的元素<br>想转化成通过名称访问的元素
利用collections.nameetuple() func 来使用一个普通的tuple帮助 解决。<br>实际上 一个返回python 中标准tuple 类型的子类的工厂方法Factory Method<br>需传递一个类型名与所需字段 后其返回一个类 and  你可以初始化 此类 and 为你定义的字段传递值
End of explanation
len(sub)
addr, joined = sub
print(addr,'\n',joined)
Explanation: nametuple 实例 看起来像 一个普通的类实例 and 其跟元组类型 可交换 and 支持所有普通元组操作 如 索引 and 解压
End of explanation
def compute_cost(records):
    total = 0.0
    for rec in records:
        total += rec[1] * rec[2]
    return total
Explanation: namedtuple 's 主要用途 即 将你的代码从下标 操作解脱出来  and if 从数据库中调用中返回了很大的元组列表 and 通过通过 下标 去操作其中元素 但你 当表中添加了新的列的时候 你的代码就会出错 if 使用 namedtuple 即不会
使用普通 tuple 的代码
End of explanation
Stock = namedtuple('Stock',['name','shares','price'])
def compute_cost2(records):
    total = 0.0
    for rec in records:
        s = Stock(*rec)
    total += s.shares * s.price
    return total
Explanation: 下标操作通常会让代码表意不明 并且非常依赖记录records 的结构<br>if 出现 歧义
End of explanation
s = Stock('Ace',100,98.9)
s
s.shares
s.shares = 98
Explanation: namedtuple 另一个用途 是作为dict 的替代 because dict 存储需要更多的内存空间 and 需要构建一个非常大的包含字典的数据结构 and 使用命名元组会更加高效 BUT 不像dict 一个namedtuple 是不可更改
End of explanation
s2 = s._replace(shares=98)
print(s,'\n',s2)
Explanation: 以上不能使用  s.shares = 98<br> if want to change the attr 可以使用namedtuple instance 's _replace() and 其会创建一个全新的namedtuple and 将对应字段用新的值取代
End of explanation
# Create a ST type
ST = namedtuple('ST',['name','share','price','date','time'])
# Create a prototype instance
ST_prototype = ST('', 0, 0.0, None, None)
# Function to convert a dictionary to a ST
def dict_to_ST(s):
    return ST_prototype._replace(**s)
a = ('hi',1,12,'2016-09-10','18:19:18')
dict_to_ST(a)
a = {'name':'hi','share':1,'price':12,'date':'2016-09-10','time':'18:19:18'}
dict_to_ST(a)
Explanation: _replace() method and 有用特性 is 当你namedtuple 拥有可选或缺失字段时， 他是个超级方便填充数据的方法 可以先创建一个内含默认值 的原型(初态)tuple and 使用_replace() 创建新值被更新过的instance
End of explanation
# want to 平方和
nums = [1,2,3,4,5,6]
s = sum(x * x for x in nums)
s 
# Determine if any .py files exist in a directory
# 判断 python 文件是否存在此目录中
# 只要有一个py file 存在 any() return True
import os
files = os.listdir('f:\Save\python')
if any(name.endswith('.py') for name in files):
    print('There be python file!')
else:
    print('Sorry no python.')
# Output a tuple as CSV
s = ('ACME',50,123.34)
print(','.join(str(x) for x in s))
# Data reduction across fileds of a data structure
portfolio = [
    {'name':'GOOG','share':50},
    {'name':'Yahoo','share':75},
    {'name':'ALO','share':20},
    {'name':'CSX','share':85}
]
min_share = min(s['share'] for s in portfolio)
min_share
Explanation: if you目标是一个需要更新很多instance's attr 高效的数据结构 BUT namedtuple is not 最佳选择 YOU can 使用一个包含 _slots_ method 的类<br>REF: chp 8.4
1.19 转换并同时计算数据
需要在data sequence 上执行聚集func (sum(),min(),max()) BUT 首先需要转换数据或者过滤数据
结合数据计算与转换 使用一个生成器表达式 参数
End of explanation
s = sum((x * x for x in nums)) # 显示的传递一个生成器表达式对象
s = sum(x * x for x in nums) # 更加优雅的实现方式 省略了括号
Explanation: 上述是将 生成器表达式 作为一个单独 argument 传递给func 时候 的巧妙语法 (不需要多加一个括号) 加不加括号 两者等效
End of explanation
s = sum([x * x for x in nums])
s
Explanation: 使用一个生成器表达式作为 argument 会比先创建一个临时列表更加高效 and 优雅
End of explanation
# Odiginal : Return 20
min_s1 = min(s['share'] for s in portfolio)
# Alternative : Return ['name':'AOL,'share':20]
min_s2 = min(portfolio, key=lambda s:s['share'])
print(min_s1,'\n',min_s2)
Explanation: 以上多创建临时列表 速度会变慢 即将会创建一个巨大的仅仅被使用一次就被丢弃的临时数据结构!!!!!!
End of explanation
<END_TASK>