- 列表去重有多少种办法?
#!usr/bin/env python
#encoding:utf-8
'''
__Author__:沂水寒城
功能:去除列表中的重复元素
'''
def func1(one_list):
'''
使用集合,个人最常用
'''
return list(set(one_list))
def func2(one_list):
'''
使用字典的方式
'''
return {}.fromkeys(one_list).keys()
def func3(one_list):
'''
使用列表推导的方式
'''
temp_list=[]
for one in one_list:
if one not in temp_list:
temp_list.append(one)
return temp_list
def func4(one_list):
'''
使用排序的方法
'''
result_list=[]
temp_list=sorted(one_list)
i=0
while i
- lambda表达式是什么?
lambda表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。
abc = lambda x,y : x+y
- 函数是编程中的map、reduce、filter、sorted等都是用作什么的?
函数式编程就是允许函数可以为参数,传入另一个函数,还允许返回一个函数
#-*- coding :UTF-8 -*-
#python 函数式编程
#允许把函数本身作为参数,传入另一个函数,还允许返回一个函数
#===>高度抽象的编程方法
#1,map()
#两个传入参数:函数对象;Iterable(list,turple,dict)
def multi(x):
a=x*x
return a
r=map(multi,[1,2,3,4,5])
#r是一个惰性序列,需要用list计算
print(list(r))
#2,reduce()
#reduce 把一个函数作用在一个序列上
#reduce(f,[x1,x2,x3,x4])=f(f(f(x1,x2),x3),x4)
from functools import reduce
def add(x,y):
a=x+y
return a
r=reduce(add,[1,2,3,4,5,6])
print(r)
def char2num(s):
return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
def num(x,y):
a=x*10+y
return a
print(reduce(num,map(char2num,'13579')))
#practice1 intput['adam', 'LISA', 'barT'],output['Adam', 'Lisa', 'Bart']
def normalize(word):
first=word[0].upper()
rest=word[1:].lower()
return first+rest
L1=['adam', 'LISA', 'barT']
L2=list(map(normalize,L1))
print(L2)
#3,filter()
#输入函数和字符串,函数依次作用于字符串的每个元素,根据返回值true/false决定保留或者丢弃
def is_odd(n):
return n%2 == 1
print(list(filter(is_odd,[1,2,3,4,5,6,7])))
#删除序列中的空字符串
#strip的用法
s=['Facebook;Google+;MySpace', 'Apple;Android']
s1=[ele.strip(' ').split(';') for ele in s]
print(s1)
#s=['A', '', 'B', None, 'C', ' ']
#s2=[ele.strip() for ele in s]
#print(s1)
def un_blank(s):
return s and s.strip()
print(list(filter(un_blank,['A', '', 'B', None, 'C', ' '])))
#用filter求素数
def _init():
n=1
while True:
n=n+2
yield n
def not_dividible(n):
return lambda x :x%n>0
#lamda用法:能够嵌入到其他表达式中的隐藏函数
# 在表达式中重新定义一个函数,不需要把定义和表达式分开
# 限制,只能由一条表达式去组成
def prime():
n=2
it=_init()
while True:
n=next(it)
yield n
it=filter(not_dividible(n),it)
for n in prime():
if n<600:
print(n)
else:
break
#filter也是惰性计算,这里n表示的是全体素数
#practice,用filter过滤掉非回数
def _init():
n=1
while True:
n=n+1
yield n
def back(n):
n=str(n)
m=n[-1::-1]
return lambda n :n==m
def prime():
yield 1
it=_init()
while True:
n=next(it)
yield n
it=filter(back(n),it)
for n in prime():
if n < 500:
print(n)
else:
break
还是不清楚在哪里出错了
def back(n):
n=str(n)
m=n[-1::-1]
# return lambda n :n==m
if m==n:
return True
else:
return False
print(list(filter(back,range(12580,13580))))
#4,sort排序算法
#按照绝对值大小排队
print(sorted([36,5,-12,5,-21],key=abs))
#按照字符串长度排序
print(sorted(['gakki','umr','toda','emma'],key=str.lower))
#按照字符串长度反向排序
print(sorted(['gakki','umr','toda','emma'],key=str.lower,reverse=True))
- 列表中的元素通过下标取值以后,是复制还是非复制(浅拷贝深拷贝)
在 python 中,标识一个对象唯一身份的是:对象的id(内存地址),对象类型,对象值,而浅拷贝就是创建一个具有相同类型,相同值但不同id的新对象。
- 应用的范围:
(1) 切片可以应用于:列表、元组、字符串,但不能应用于字典。
(2) 深浅拷贝,既可应用序列(列表、元组、字符串),也可应用字典。
- 深浅拷贝的作用:
不可变对象类型,没有被拷贝的说法,即便是用深拷贝,查看id的话也是一样的,如果对其重新赋值,也只是新创建一个对象,替换掉旧的而已。
一句话就是,不可变类型,不管是深拷贝还是浅拷贝,地址值和拷贝后的值都是一样的。
- 对于不可变对象的深浅拷贝:
不可变对象类型,没有被拷贝的说法,即便是用深拷贝,查看id的话也是一样的,如果对其重新赋值,也只是新创建一个对象,替换掉旧的而已。
一句话就是,不可变类型,不管是深拷贝还是浅拷贝,地址值和拷贝后的值都是一样的。
a=(1,2,3)
print("=====第一种=号浅拷贝=====")
b=a
print(a)
print(b)
print(id(a))
print(id(b))
print("=====另一种copy浅拷贝===")
b=copy.copy(a)
print(a)
print(b)
print(id(a))
print(id(b))
print("=====深拷贝=====")
b=copy.deepcopy(a)
print(a)
print(b)
print(id(a))
print(id(b))
# 结果如下:
=====浅拷贝=====
(1, 2, 3)
(1, 2, 3)
2814522335952
2814522335952
=====另一种浅拷贝===
(1, 2, 3)
(1, 2, 3)
2814522335952
2814522335952
=====深拷贝=====
(1, 2, 3)
(1, 2, 3)
2814522335952
2814522335952
- 对于可变对象深浅拷贝:
=浅拷贝:值相等,地址相等
copy浅拷贝:值相等,地址不相等
deepcopy深拷贝:值相等,地址不相等
a=[1,2,3]
print("=====第一种=号浅拷贝=====")
b=a
print(a)
print(b)
print(id(a))
print(id(b))
print("=====另一种copy浅拷贝===")
b=copy.copy(a)
print(a)
>print(b)
print(id(a))
print(id(b))
print("=====深拷贝=====")
b=copy.deepcopy(a)
print(a)
print(b)
print(id(a))
print(id(b))
#结果如下:
=====浅拷贝=====
[1, 2, 3]
[1, 2, 3]
2007696321544
2007696321544
=====另一种copy浅拷贝===
[1, 2, 3]
[1, 2, 3]
2007696321544
2007695909960
=====深拷贝=====
[1, 2, 3]
[1, 2, 3]
2007696321544
2007696319560
结论:
(1) 深浅拷贝都是对源对象的复制,占用不同的内存空间。
(2) 不可变类型的对象,对于深浅拷贝毫无影响,最终的地址值和值都是相等的。
可变类型:
(1) =浅拷贝: 值相等,地址相等
(2) copy浅拷贝:值相等,地址不相等
(3) deepcopy深拷贝:值相等,地址不相等
- 生成器,迭代器和装饰器
生成器算得上是Python语言中最吸引人的特性之一,生成器其实是一种特殊的迭代器,不过这种迭代器更加优雅。它不需要再像上面的类一样写iter()和next()方法了,只需要一个yiled关键字。 生成器一定是迭代器(反之不成立),因此任何生成器也是以一种懒加载的模式生成值。
那么什么迭代器呢?它是一个带状态的对象,他能在你调用next()方法的时候返回容器中的下一个值,任何实现了iter和next()(python2中实现next())方法的对象都是迭代器,iter返回迭代器自身,next返回容器中的下一个值,如果容器中没有更多元素了,则抛出StopIteration异常
python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能
举一个装饰器的例子:
这是我们最原始的的一个函数,然后我们试图记录下这个函数执行的总时间,那最简单的做法就是:
#原始侵入,篡改原函数
import time
def func():
startTime = time.time()
print("hello")
time.sleep(1)
print("world")
endTime = time.time()
msecs = (endTime - startTime)*1000
print("time is %d ms" %msecs)
但是如果你的Boss在公司里面和你说:“小祁,这段代码是我们公司的核心代码,你不能直接去改我们的核心代码。”那该怎么办呢,我们仿照装饰器先自己试着写一下:
避免直接侵入原函数修改,但是生效需要再次执行函数
import time
def deco(func):
startTime = time.time()
func()
endTime = time.time()
msecs = (endTime - startTime)*1000
print("time is %d ms" %msecs)
def func():
print("hello")
time.sleep(1)
print("world")
if __name__ == '__main__':
f = func
deco(f)#只有把func()或者f()作为参数执行,新加入功能才会生效
print("f.__name__ is",f.__name__)#f的name就是func()
print()
#func()
- 斐波那契数列
f(3) =f(1)+f(2)
f(n+2)=f(n)+f(n+1)
f(1)=f(2)=1
当n=100时,求f(n)?
由题可知,这是一个斐波那契?
# -*- coding:utf-8 -*-
# 第一种
def fab(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a+b
n += 1
for i in fab(5):
print i
# 第二种
def Fibonacci_Recursion_tool(n):
if n <= 0:
return 0
elif n == 1:
return 1
else:
return Fibonacci_Recursion_tool(n-1)+Fibonacci_Recursion_tool(n-2)
def Fibonacci_Recursion_list(n):
lis = []
for i in xrange(1, n+1):lis.append(Fibonacci_Recursion_tool(i))
return lis
print Fibonacci_Recursion_list(5)
#第三种
resu_list = []
def fibo(n):
for i in xrange(n):
if i == 0 or i == 1:
resu_list.append(i)
else:
resu_list.append(resu_list[i-1]+resu_list[i-2])
return resu_list
print fibo(20)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]
#第四种
a = 0
b = 1
while b < 1000:
print(b,end=',')
a, b = b, a+b
#第五种
# -*- coding:utf-8 -*-
class Fib(object):
def __init__(self):
pass
def __call__(self, num):
a, b = 0, 1;
self.l = []
for i in range(num):
self.l.append(a)
a, b = b, a + b
return self.l
def __str__(self):
return str(self.l)
__repr__ = __str__
f = Fib()
print f(3)
[0, 1, 1]
- 求解(时间复杂度):
[1,3,5,7,9]
求5的0(1)?
- dict中的items()与iteritems()区别:
items() 返回的类似列表中每个元素都是元祖的对象
而iteritems()返回的是一个迭代器
- _new_,_call_,_str_,_repr_,_setattr_ ,_len_,_iter_,_next_魔法含义?
- _new_()方法定义为静态方法,并且至少需要传递一个参数cls,cls表示需要实例化的类,此参数在实例化时由Python解释器自动提供。_new_是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例,是个静态方法。
# -*- coding:utf-8 -*-
import json
class A(object):
n = 0
def __new__(cls, *args, **kwargs):
return 'abc'
def __init__(self):
pass
print A()
/usr/bin/python /Users/admin/Documents/devops_object/PycharmProjects/untitled/ceshi1.py
abc
- _call_()可以将一个类实例变成一个可调用对象
class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
def __call__(self, friend):
print 'My name is %s...' % self.name
print 'My friend is %s...' % friend
>>> p = Person('Bob', 'male')
>>> p('Tim')
My name is Bob...
My friend is Tim...
3._len_
# -*- coding:utf-8 -*-
class test:
def __len__(self):
return 5
print(len(test()))
######输出######
5
4._iter_,_next_,
对于test这个类来说,它定义了iter和next函数,所以是一个可迭代的类,也可以说是一个可迭代的对象(Python中一切皆对象)。
含有next()函数的对象都是一个迭代器,所以test也可以说是一个迭代器。如果去掉itet()函数,test这个类也不会报错
```class test():
def __init__(self,data=1):
self.data = data
def __iter__(self):
return self
def __next__(self):
if self.data > 5:
raise StopIteration
else:
self.data+=1
return self.data
for item in test(3):
print(item)
######输出######
4
5
6
class test():
def __init__(self,data=1):
self.data = data
def __next__(self):
if self.data > 5:
raise StopIteration
else:
self.data+=1
return self.data
t = test(3)
for i in range(3):
print(t.__next__())
######输出######
4
5
6
- channel,tornado,twisted,html+css+js
>
- 协程的例子
>yield 关键字的循环,就是一个协程处理的过程。
- 字符串/列表的倒序
>a = 'abcdefg'
print a[::-1]
b = [1,2,3,4,5]
print b.reverse()
- sort /sorted 相关的用法
>
- type()和isinstance()区别
>1. isinstance效率更高一些
>2. type可以只接收一个参数,打印其未知的所属的类型;而isinstance只能判断是否属于某个已知类型。
>3. type()不能判断子类是父类的一种类型,而isinstance()可以
例子:
```# -*- coding:utf-8 -*-
class A(object):
pass
class B(A):
pass
print type(B()) == A
print isinstance(B(),A)
False
True
- 静态方法,类方法
- 静态方法:
静态方法是类中的函数,不需要实例。静态方法主要是用来存放逻辑性的代码,主要是一些逻辑属于类,但是和类本身没有交互,即在静态方法中,不会涉及到类中的方法和属性的操作。可以理解为将静态方法存在此类的名称空间中。
- 类方法:
类方法是将类本身作为对象进行操作的方法。他和静态方法的区别在于:不管这个方式是从实例调用还是从类调用,它都用第一个参数把类传递过来。
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
class Date(object):
day = 0
month = 0
year = 0
def __init__(self, day=0, month=0, year=0):
self.day = day
self.month = month
self.year = year
@classmethod
def from_string(cls, date_as_string):
day, month, year = map(int,date_as_string.split('-'))
date1 = cls(day, month, year)
return date1
@staticmethod
def from_string1(date_as_string):
data1 = map(str,date_as_string.split('-'))
return data1
date2 = Date.from_string('11-09-2012')
print type(date2.day), date2.day
print Date.from_string1('11-09-2012')
11
['11', '09', '2012']
- 异常类
NotImplementedError
Python编程中raise可以实现报出错误的功能,而报错的条件可以由程序员自己去定制。在面向对象编程中,可以先预留一个方法接口不实现,在其子类中实现。
class ClassDemo:
def test_demo(self):
raiseNotImplementedError("my test: not implemented!")
class ChildClass(ClassDemo):
pass
inst =ChildClass()
inst.test_demo()
E:\01_workspace\02_programme_language\03_python\OOP\2017\08\10>pythonerror_demo.py
Traceback (mostrecent call last):
File "error_demo.py", line 9, in
inst.test_demo()
File "error_demo.py", line 3, intest_demo
raise NotImplementedError("my test:not implemented!")
NotImplementedError:my test: not implemented!
上面的报错是,子类test_demo没有在类中ChildClass调用,所以会报错
下面正确的更改是:
class ClassDemo:
def test_demo(self):
raiseNotImplementedError("my test: not implemented!")
class ChildClass(ClassDemo):
def test_demo(self)
print "OK"
inst =ChildClass()
inst.test_demo()
E:\01_workspace\02_programme_language\03_python\OOP\2017\08\10>pythonerror_demo.py
OK
这样就可以了。
- Unicode 转Python字符串
# -*- coding:utf-8 -*-
import json
u_str = u"abc"
print type(u_str)
print type(u_str.encode("utf-8"))
/usr/bin/python /Users/admin/Documents/devops_object/PycharmProjects/untitled/ceshi1.py
- 使用装饰器实现单例模式
# -*- coding:utf-8 -*-
import json
def singleton(cls, *args, **kwargs):
instance = {}
def _instance():
if cls not in instance:
instance[cls] = cls(*args, **kwargs)
print 1
return instance[cls]
return _instance
@singleton
class Test_singleton:
def __init__(self):
self.num = 0
def add(self):
self.num = 99
t1 = Test_singleton()
t2 = Test_singleton()
print t1
print t2
/usr/bin/python /Users/admin/Documents/devops_object/PycharmProjects/untitled/ceshi1.py
1
<__main__.Test_singleton instance at 0x1093ab638>
<__main__.Test_singleton instance at 0x1093ab638>
- Python: 为对象动态添加函数,且函数定义来自一个str
# -*- coding:utf-8 -*-
import time
import new
method_str = u'''
def say(self, name):
print 'My name is', name
'''
class MyClass:
def __init__(self):
pass
# def extends(self, method_name, method_str):
# pass
def extends(self, method_name, method_str):
_method = None
exec method_str +'''\n_method = %s'''% method_name
self.__dict__[method_name] = new.instancemethod(_method, self, None)
new.instancemethod(_method, self, None)
obj =MyClass()
obj.extends('say', method_str)
obj.say('wendal')#打印出My name is wendal
###########################################################
一个带有 yield 的函数就是一个 generator,它和普通函数不同,生成一个 generator 看起来像函数调用,但不会执行任何函数代码,直到对其调用 next()(在 for 循环中会自动调用 next())才开始执行。虽然执行流程仍按函数的流程执行,但每执行到一个 yield 语句就会中断,并返回一个迭代值,下次执行时从 yield 的下一个语句继续执行。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。
- yield from
# -*- coding:utf-8 -*-
a = 'abc'
b = [1,2,3,4,5,6]
c = {"a":1, "b":2}
agen = (i for i in range(4, 8))
def test(*args, **kwargs):
for item in args:
yield from item
new_list = test(a,b,c,agen)
print(list(new_list))
######输出########
['a', 'b', 'c', 1, 2, 3, 4, 5, 6, 'a', 'b', 4, 5, 6, 7]
- yield
def test(n):
for i in range(n):
yield i
for x in test(20):
print(x)
######输出######
0
1
2
3
4