enumerate方法迭代
在for迭代过程中,如果想要同时获取值和索引,可以采用enumerate方法,用法如下:
L = ["asdf",1,5]
for i,value in enumerate(L):
print(i,value) #i = index, value = object
常用场景为,给出一个可迭代对象,如list,返回对象的最大值和其索引
L = [1,2,3,4,5]
def findMaxAndIndex(L):
tempMax = L[0]
tempIndex = 0
for index,value in enumerate(L):
if tempMax <= value:
tempMax = value
tempIndex = index
return(tempMax, tempIndex)
print(findMaxAndIndex(L))
另外,enumerate(seq, start),默认start是从0开始索引,如果要改变为从1开始索引,可以改为for i,value in enumerate(L,1):
切片
凡是可迭代对象,如list, tuple, str都具有切片功能
L = list(range(100))
L[:10] #前10个数
L[-10:] #后10个数
L[::2] #step为2
列表生成式
对于迭代式,可以直接将迭代对象进行筛选和操作,写在一行表达式。
如下例,筛选出range(1,6)中的偶数,并取平方:
list1=[1,2,3,4,5]
list2 = [x*x for x in list1 if x%2==0] #注意,这里是条件筛选,不要加else
print(list2)
generator生成器
与列表生成式的区别就是[]和()的区别,generator采用()
列表生成式受到内存限制,容量有限。
如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
g = (x*x for x in range(1,6))
for i in g:
print(i)
迭代器Iterator
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
-凡是可作用于for循环的对象都是Iterable类型;
-凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
若使一个函数变为Iteraotor,则需要使用关键词yield
函数传参*arg, **kwarg
*arg 表示传入的参数未知数量,以tuple形式传入
def func1(*arg):
for i in arg:
print(i)
func1(1,2,3)
*kwarg 表示传入的参数为dict
def func2(*kwarg):
for key, value in kwarg.items():
print(str(key)+':'+str(value))
dict1 = {'a':1, 'b':2, 'c':3}
func2(**dict1)
zip打包函数
zip() 函数用于将可迭代的对象作为参数,将对象中对应索引的元素打包成一个个元组,然后返回由这些元组组成的列表。
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> c = [4,5,6,7,8]
>>> zipped = zip(a,b) # 打包为元组的列表
[(1, 4), (2, 5), (3, 6)]
>>> zip(a,c) # 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]
类的继承方法super
子类继承父类时,典型场景会重写父类方法,如__init__()。若用户希望保留父类构造方法的基础上新增功能,则需要利用到super()这种方法。
- Python3 可以直接写super().init()
- Python2需要写super(类名, self).init()
- 注意,super方法也需要根据继承原函数进行传参,若父类__init__(self, name), 则子类也需要super().init(name)
举例如下:
class Person(object):
def __init__(self, name, age):
self.name = name
self.__age = age
def say_hi(self):
print('I am the parent')
@property
def age(self):
return self.__age
@age.setter
def age(self, _age):
self.__age = _age
class Employee(Person):
def __init__(self, name, age, user_id):
super(Employee, self).__init__(name, age) # Python3 可以直接写super().__init__(), 而Python2需要写super(类名, self).__init__()
self.user_id = user_id
def say_hi(self):
super().say_hi() # 继承父类say_hi,并新增功能
print('I am the child')
if __name__ == '__main__':
Lisa = Employee('Lisa', 18, 1001)
Lisa.say_hi()
类的__init__, call
类在实例化之后,便会自动调用其构造方法__init__()
实例化后的类在调用时,会自动调用其__call__()方法,
class ob1:
def __init__(self, name, age):
print('__init__ here')
self.name = name
self.age = age
def __call__(self):
print('__call__ here')
o = ob1('Richard',26)
# __init__ here
o()
#__cal__ here
装饰器property
为了避免类的属性在用户调用时发生赋值错误,常将重要属性设置为私有属性。但私有属性带来的问题是,经常要定义私有属性的get和set方法,用户调用时也不方便。
为了解决这类问题,python可支持装饰器的作用,将函数装饰为属性,并为其增加get和set方法。例如:
土鳖方法定义类的get和set方式
class Person(object):
def __init__(self, name, age):
self.name = name
self.__age = age # 私有属性,需要定义get和set方法
def get_age(self):
return self.__age
def set_age(self, age):
if age > 0:
self.__age = age
else:
print('年龄小于0,输入错误')
装饰器方法定义
class Person(object):
def __init__(self, name, age):
self.name = name
self.__age = age
@property
def age(self):
return self.__age
@age.setter
def age(self, _age):
if age > 0:
self.__age = age
else:
print('年龄小于0,输入错误')