如何在列表,字典,集合中根据条件筛选数据?
通常使用迭代条件语句;此外还可以使用以下方法:
1、列表 {filter函数:filter{lambda x:x>=0,data};列表解析:[x for x in data if x>=0]; { f i l t e r 函 数 : f i l t e r { l a m b d a x : x >= 0 , d a t a } ; 列 表 解 析 : [ x f o r x i n d a t a i f x >= 0 ] ;
2、字典——字典解析:{k: v for k,v in d.iteritems() if v>90};
3、集合——集合解析:{x for x in s if x % 3==0};
如何为元组中每个元素命名,提高程序的可读性
方案一:定义一系列的数据常量,用数据常量表示字段序号
方案二:使用标准库中collections.namedtuple替代内置tuple
from collections import namedtuple
##这个函数可以返回一个内置元组的子类
Student = namedtuple('Student',['name','age','sex','email'])
##给新创建的子类起一个名字,传入再每一个索引的名字,并指向一个Student的构造器
s=Student('Jim',16,'male','666@qq.com')
##使用创建的元组类子类来构造元组,s是一个命名了的元组
s.name
##以类对象的属性的方式来访问元组
如何统计序列中元素的出现频率
方案一:
from random import randint
data=[randint(0,20) for _ in range(30)]
##要求统计结果以字典形式
c= dict.fromkeys(data,0)
##以data中的每一个元素作为键,0作为初始值创建字典
for x in data:
c[x]+=1
方案二:使用collections.Counter对象将序列传入Counter的构造器,得到Counter对象是元素频率的字典。Counter.most_common(n)方法得到频度最高的n个元素的列表。
from collections import Counter
c2=Counter(data)
##c2可以像字典一样通过键来访问得到每个元素的频率
c2.most_common(3)
##找到出现频度最高的三个元素
如何根据字典中值的大小,对字典中的项进行排序
方案一:使用内置函数sorted,利用zip将字典数据转换为元组
from random import randint
d={x:randint(60,100)for x in 'xyzzbc'}
##创建一个字典
sorted(d)
##按照键来排序
(97,'a')>(69,'b')
##元组比较,返回True,先比较元组的第一项,再比第二项
(97,'a')>(97,'b')
##返回False,第一个元素相等,但第二个元素a比b小
zip(d.values(),d.keys())
##构成一个元组的列表
a=zip(d.itervalues(),d.iterkeys())
##更节省空间,提高运行速度
sorted(a)
方案二:传递sorted函数的key参数
d.items()
#返回键值对列表
sorted(d.items(),key=lambda x:x[1])
##指定键值
如何快速找到多个字典中的公共键
方案:使用集合set()的交集操作。使用字典viewkeys()的方法,得到一个字典keys的集合,使用map函数得到所有字典keys的集合;使用reduce函数,取得所有字典keys的集合交集
from random import randint,sample
sample('abcdefg',3)
##随机取样3个,返回例如['c','d','b']
sample('abcdefg',randint(3,6))
##每次随机取3~6个样本
s1={x:randint(1,4)for x in sample('abcdefg',randint(3,6))}
##用相同的字典解析,产生s2,s3
s1.viewkeys () &s2.viewkeys ()&s3.viewkeys ()
##得到s1,s2,s3的键并集
##对于n个字典,则使用map和reduce,重复执行函数
ab=map(dict.viewkeys,[s1,s2,s3])
reduce(lambda a,b:a&b,ab)
如何让字典保持有序
python中的字典不具备有序性,不维护每个项进入的前后次序
方案:使用collections. OrderedDict ,以 OrderedDict替代内置字典Dict,依次存入数据
from collections import OrderedDict
d=OrderedDict()
d['jim']=1
d['bob']=2
d['leo']=3
for k in d:print k
##按每个项进入的顺序遍历
如何实现用户的历史记录功能
方案:使用容量为n的队列存储历史记录
使用标准库collections中的deque,它是一个双端循环队列
程序退出前,可以使用pickle将队列对象存入文件,再次运行程序时将其导入
from collections import deque
q=deque([],5)
##传入两个参数,一个是队列初始值,一个队列容量
q.append(1)
##入队元素,当超过5个时第一个会被挤出去
如何实现可迭代对象和迭代器对象?
案例:从网络上抓取各个城市气温信息,并依次显示,采用“用时访问”策略,并把所有城市气温封装到一个对象里,可用for进行迭代
方案:实现一个迭代器对象WeatherIterator,next方法每次返回一个城市气温
实现一个可迭代对象WeatherIterable,__iter__ 方法返回一个迭代器对象
##列表和字符串都是可迭代对象
##可迭代对象可使用内置函数iter()得到一个迭代器对象
##可迭代器只有next()方法
import requests
from collections import Iterator,Iterable
##Iterator的接口是next(),Iterable的接口是__iter__
class WeatherIterator(Iterator):
def __init__(self,cities):##构造器
self.cities=cities
self.index=0
def getWeather(self,city):
r = requests.get(u'http:/wthrcdn.etouch.cn/weather_mini?city='+city)
data = r.json()['data']['forecast'][0]
return '%s:%s,%s'%(city,data['low'],data['high'])
def next(self):
if self.index==len(self.cities):
raise StopIteration##抛出异常
city = self.cities[self.index]
self.index+=1
return self.getWeather(city)
class WeatherIterable(Iterable):
def __init__(self,cities):
self.cities = cities
def __iter__(self):
return WeatherIterator(self.cities)
##执行
for x in WeatherIterable([u'北京',u'上海',u'广州']):
print(x)
如何使用生成器函数实现可迭代对象
案例:实现一个可迭代对象的类,它能迭代出给定范围内的所有素数
方案:将该类的__iter__ 方法实现生成器函数,每次yield返回一个素数
##包含yield的函数即生成器函数,这个函数调用时不会直接执行函数体内部的语句,
##而是返回一个生成器对象,支持next()方法(迭代器接口)
##生成器对象同时也可以是可迭代对象,
##即可放在in后面,说明使用了__iter__()方法(可迭代接口)
class PrimeNumbers:
def __init__(self,start,end):
self.start=start
self.end=end
def isPrimeNum(self,k):
if (k<2):
return False
for i in range(2,k):
if k % i ==0:
return False
return True
def __iter__(self):
for k in range(self.start,self.end+1):
if self.isPrimeNum(k):
yield k
##测试
for x in PrimeNumbers(1,100):
print(x)
如何进行反向迭代以及如何实现反向迭代
##关于序列的反向迭代
l=[1,2,3,4,5]
#切片操作得到
l[::-1]
##使用内置函数reversed(),得到一个反向迭代器,iter()得到一个正向迭代器
for x in reversed(l):
print(x)
##实现反向迭代
class FloatRange:
def __init__(self,start,end,step=0.1):
self.start=start
self.end=end
def __iter__(self):
t = self.start
while t <=self.end
yield t
t+=self.stop
def __reversed__(self):
t=self.end
while t>=self.start
yield t
t-=self.step
##测试
for x in reversed(FloatRange(1.0,4.0,0.5)):
print(x)
如何对迭代器做切片操作
方案:使用标准库中的itertools.islice,它能返回一个迭代对象切片的生成器
##文本文件可以作为迭代器,但不能进行切片操作
##可以通过readlines读取所有行,并储存进列表
lines=f.readlines()
lines[100,300]
#通过line逐行读取,readlines()将指针指向最后一行,需要用seek()方法返回到文件的头部
f.seek(0)
for line in f:
print(line)
from itertools import islice
t=islice(f,100,300)
for line in t:
print(line)
##可以使用None来省略开始结束
##会消耗迭代对象,即指针会移动到结束位置
如何在一个for语句中迭代多个可迭代对象
方案一:(并行)使用内置函数zip,它能将多个可迭代对象合并,每次迭代返回一个元组
方案二:(串行)使用标准库中的itertools.chain,它能将多个可迭代对象连接
##举例
from random import randint
chinese=[randint(60,100)for _ in range(40)]
math=[randint(60,100)for _ in range(40)]
english=[randint(60,100)for _ in range(40)]
##方案:使用索引的方式进行访问(局限性:不能访问迭代器)
for i in range(len(math)):
chinese[i]+math[i]+english[i]
##方案一:三个列表要一样大,并联起来
total=[]
for c,m,e in zip(chinese,math,english):
total.append(c+m+e)
##方案二:三个列表可以不一样大,串联起来
from itertools import chain()
for x in chain(chinese,math,english):
if (x >=90):
print(x)