常用内置函数
1. min 和 max
min() 方法返回给定参数的最小值,参数可以为序列或其它可迭代对象。
max() 方法返回给定参数的最大值,参数可以为序列或其它可迭代对象。
注:max 或者 min 比较的是元素和元素之间的大小,是元素的整体比较,而不是元素的每个位比较。
print(max(1, 2, 3, 4, 5)) print(max([1, 2, 3, 4, 5])) print(max("abcde")) # 对tuple的每个元素比较,前面的元素如果已经分出大小,后面的便不在比较了 x = [(1, 3), (1, 4), (-1, 12), (0, 100)] print(min(x)) # (-1, 12)
2. sorted
sorted() 函数对所有可迭代的对象进行排序操作,默认为升序。函数原型如下:
""" iterable -- 可迭代对象。 key -- 用来进行比较的元素,只有一个参数,具体的函数的参数取自于可迭代对象中,指定按可迭代对象中的某个元素来进行排序。 reverse -- 排序规则,reverse = True 降序 , reverse = False 升序(默认) """ sorted(iterable, key=None, reverse=False)
下面来看几个例子:
print(sorted([5, 2, 3, 1, 4])) # [1, 2, 3, 4, 5] print(sorted([5, 2, 3, 1, 4], reverse=True)) # [5, 4, 3, 2, 1] print(sorted([5, 2, 3, 1, 4], key=lambda x: x * -1)) # [5, 4, 3, 2, 1] students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10), ] print(sorted(students, key=lambda student: student[2])) # sort by age """ [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] """ array = [{"age": 20, "name": "a"}, {"age": 25, "name": "b"}, {"age": 10, "name": "c"}] array = sorted(array, key=lambda x: x["age"]) print(array) """ [{'age': 10, 'name': 'c'}, {'age': 20, 'name': 'a'}, {'age': 25, 'name': 'b'}] """ d = [{'name': 'alice', 'score': 38}, {'name': 'bob', 'score': 18}, {'name': 'darl', 'score': 28}, {'name': 'christ', 'score': 28}] y = sorted(d, key=lambda x: (-x['score'], x['name'])) # 先按照成绩降序排序,相同成绩的按照名字升序排序: print(y) """ [{'name': 'alice', 'score': 38}, {'name': 'christ', 'score': 28}, {'name': 'darl', 'score': 28}, {'name': 'bob', 'score': 18}] """ # 字典是无序的,不能排序,sorted只是排序 d 的 键值对 元组的列表。 d = {1: 'D', 2: 'B', 3: 'B', 4: 'E', 5: 'A'} print(sorted(d.keys())) print(sorted(d.items())) """ [1, 2, 3, 4, 5] [(1, 'D'), (2, 'B'), (3, 'B'), (4, 'E'), (5, 'A')] """ class User: def __init__(self, user_id): self.user_id = user_id def __repr__(self): return 'User({})'.format(self.user_id) users = [User(23), User(3), User(99)] print(sorted(users, key=lambda u: u.user_id))
3. map
map(function, iterable, ...)会根据提供的函数对指定序列做映射。第一个参数 function 以参数序列中的每一个元素作为其参数,
每次 function 函数的返回值组成新列表返回。不同的是:Python 2.x 返回列表,Python 3.x 返回迭代器。
def square(x): # 计算平方数 return x ** 2 print(list(map(square, [1, 2, 3, 4, 5]))) # [1, 4, 9, 16, 25] print(list(map(lambda x: x ** 2, [1, 2, 3, 4, 5]))) # [1, 4, 9, 16, 25] # 提供了两个列表,对相同位置的列表数据进行相加 print(list(map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10]))) # [3, 7, 11, 15, 19]
4. filter
filter(function, iterable) 函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list() 来转换。
该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。
def is_odd(n):
return n % 2 == 1
tmplist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
newlist = list(tmplist)
print(newlist) # [1, 3, 5, 7, 9]
5. zip
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象。
python2的该函数会直接返回list,但python3需要再用list()转换来输出列表。
如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同。直接看个例子:
a = [1, 2, 3] b = [4, 5, 6] c = [4, 5, 6, 7, 8] d = list(zip(a, b, c)) print(d) # [(1, 4, 4), (2, 5, 5), (3, 6, 6)]
为了对字典值执行计算操作,通常需要使用 zip() 函数先将键和值反转过来。比如,下面是查找最小和最大股票价格和股票值的代码:
prices = { 'ACME': 45.23, 'AAPL': 612.78, 'IBM': 205.55, 'HPQ': 37.20, 'FB': 10.75 } min_price = min(zip(prices.values(), prices.keys())) print(min_price)
需要注意的是 zip() 函数创建的是一个只能访问一次的迭代器,所以对一个zip对象,只能迭代一次,第二次再迭代就没有数据了。比如:
l1 = [1, 2, 3, 4] l2 = [2, 3, 4, 5] l3 = zip(l1, l2) l4 = [x for x in l3] print(l4) # [(1, 2), (2, 3), (3, 4), (4, 5)] for i in l3: print('for循环{}'.format(i)) # 输出空
6. super
super()可以用于调用父类(超类)的某个方法,并且只能用于新式类,主要用在多继承中,在单继承时直接调用父类方法即可,但是在多继承中就
会涉及到重复继承等问题,这里也需要牵涉到MRO(Method Resolution Order,方法解析顺序)。以下是 super() 方法的语法:
super(type[, self])
直接调用父类的方法在多继承中会出现问题,比如运行这段代码就会发现 Base.__init__() 被调用两次。
class Base: def __init__(self): print('Base.__init__') class A(Base): def __init__(self): Base.__init__(self) print('A.__init__') class B(Base): def __init__(self): Base.__init__(self) print('B.__init__') class C(A,B): def __init__(self): A.__init__(self) B.__init__(self) print('C.__init__') c = C() """ Base.__init__ A.__init__ Base.__init__ B.__init__ C.__init__ """
使用 super() 调用的话最终只会输出一次 Base.__init__。当你使用 super() 函数时,Python 会在 MRO 列表上按 C3 算法继续搜索下一个类。只要
每个重定义的方法统一使用 super() 并只调用它一次,那么控制流最终会遍历完整个 MRO 列表,每个方法也只会被调用一次。
class Base: def __init__(self): print('Base.__init__') class A(Base): def __init__(self): super().__init__() print('A.__init__') class B(Base): def __init__(self): super().__init__() print('B.__init__') class C(A,B): def __init__(self): super().__init__() # Only one call to super() here print('C.__init__') c = C() """ Base.__init__ A.__init__ B.__init__ C.__init__ """