Python实例(一)

如何在列表,字典,集合中根据条件筛选数据?

通常使用迭代条件语句;此外还可以使用以下方法:

1、列表 { 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','[email protected]')
##使用创建的元组类子类来构造元组,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)

猜你喜欢

转载自blog.csdn.net/zhili_wang/article/details/80952015