文章目录
zip
从参数中的多个可迭代对象中分别取元素组成元组,最后返回zip对象,可转为list查看
def zip(*iterables):
# zip('ABCD', 'xy') --> Ax By
sentinel = object()
iterators = [iter(it) for it in iterables]
while iterators:
result = []
for it in iterators:
elem = next(it, sentinel)
if elem is sentinel:
return
result.append(elem)
yield tuple(result)
例如:
a = [1,2,3,4]
b = [1,2,3]
c = zip(a,b)
print(c) # <zip object at 0x00000000020D0548>
print(list(c)) # [(1, 1), (2, 2), (3, 3)]
zip(*)
zip操作的逆操作,但是数量不一致时,无法返回原来一样的值
a = [1,2,3,4]
b = [1,2,3]
c = zip(a,b)
print(list(zip(*c))) # [(1, 2, 3), (1, 2, 3)]
list.sort()和sorted()-python3
functools.cmp_to_key(func)
python3 为什么取消了sort方法中的cmp参数?
排序指南
基本排序
list.sort():sort(*, key=None, reverse=False)
仅适合列表,直接修改原列表(并返回 None 以避免混淆),默认为升序
sorted():sorted(iterable, *, key=None, reverse=False)
可以接受任何可迭代对象,返回一个新的已排序列表,不修改原数据
a = [5,3,24,1]
b = a.sort() # 无返回值,直接修改原列表
print("a:",a,"b:",b)
a1 = [5,3,24,1]
b1 = sorted(a1) # 返回排序后的列表,不修改原列表
print("a1:",a1,"b1:",b1)
结果:
a: [1, 3, 5, 24] b: None
a1: [5, 3, 24, 1] b1: [1, 3, 5, 24]
关键函数key
key 形参的值应该是一个函数,它接受一个参数并并返回一个用于排序的键。这种技巧速度很快,因为对于每个输入记录只会调用一次 key 函数。
# 不区分大小写的字符串比较
print(sorted("This is a test string from Andrew".split(), key=str.lower))
# 使用对象的一些索引作为键对复杂对象进行排序
student_tuples = [
('john', 'A', 15),
('jane', 'B', 12),
('dave', 'B', 10),
]
print(sorted(student_tuples, key=lambda student: student[2])) # 按照年龄排序
# 具有命名属性的对象
class Student:
def __init__(self, name, grade, age):
self.name = name
self.grade = grade
self.age = age
def __repr__(self):
return repr((self.name, self.grade, self.age))
student_objects = [
Student('john', 'A', 15),
Student('jane', 'B', 12),
Student('dave', 'B', 10),
]
print(sorted(student_objects, key=lambda student: student.age))
结果:
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
Operator 模块函数
上面显示的键函数模式非常常见,因此 Python 提供了便利功能,使访问器功能更容易,更快捷。 operator 模块有 itemgetter() 、 attrgetter() 和 methodcaller() 函数。
itemgetter() :
attrgetter() :
methodcaller():
student_tuples = [
('john', 'A', 15),
('jane', 'B', 12),
('dave', 'B', 10),
]
class Student:
def __init__(self, name, grade, age):
self.name = name
self.grade = grade
self.age = age
def __repr__(self):
return repr((self.name, self.grade, self.age))
student_objects = [
Student('john', 'A', 15),
Student('jane', 'B', 12),
Student('dave', 'B', 10),
]
from operator import itemgetter,attrgetter
print(sorted(student_tuples,key=itemgetter(2))) # 按照年龄排序
print(sorted(student_objects,key=attrgetter('age')))
print(sorted(student_tuples,key=itemgetter(1,2))) # 先按 grade 排序,然后按 age 排序
print(sorted(student_objects,key=attrgetter('grade','age')))
结果:
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
升序和降序reverse
reverse 参数。reverse=False默认为升序,当reverse=True表示降序
使用 cmp 参数的旧方法
在 Py2.x 中, sort 允许一个可选函数,可以调用它来进行比较。该函数应该采用两个参数进行比较,然后返回负值为小于,如果它们相等则返回零,或者返回大于大于的正值。例如:
# python 2.x
def numeric_compare(x, y):
return x - y # return y-x为降序
print sorted([5, 2, 4, 1, 3], cmp=numeric_compare) # [1, 2, 3, 4, 5]
在 Py3.0 中, cmp 参数被完全删除(作为简化和统一语言努力的一部分,消除了丰富的比较与 cmp() 魔术方法之间的冲突)。
# python 3.x
# 或者直接导入from functools import cmp_to_key
def cmp_to_key(mycmp):
'Convert a cmp= function into a key= function'
class K:
def __init__(self, obj, *args):
self.obj = obj
def __lt__(self, other):
return mycmp(self.obj, other.obj) < 0
def __gt__(self, other):
return mycmp(self.obj, other.obj) > 0
def __eq__(self, other):
return mycmp(self.obj, other.obj) == 0
def __le__(self, other):
return mycmp(self.obj, other.obj) <= 0
def __ge__(self, other):
return mycmp(self.obj, other.obj) >= 0
def __ne__(self, other):
return mycmp(self.obj, other.obj) != 0
return K
def numeric_compare(x, y):
return x - y
print(sorted([5, 2, 4, 1, 3], key=cmp_to_key(numeric_compare)) )
应用
Leetcode的题目Largest Number:
Given a list of non negative integers, arrange them such that they form the largest number.
For example, given [3, 30, 34, 5, 9], the largest formed number is 9534330.
Note: The result may be very large, so you need to return a string instead of an integer.
from functools import cmp_to_key
nums = [3, 30, 34, 5, 9]
key = cmp_to_key(lambda x, y: int(y + x) - int(x + y))
res = ''.join(sorted(map(str, nums), key=key)).lstrip('0')
print(res) # 95343300
map
参考 :python中的map函数
map是python内置函数,会根据提供的函数对指定的序列做映射。
map()函数的格式是:
map(function,iterable,...)
第一个参数接受一个函数名,后面的参数接受一个或多个可迭代的序列,返回的是一个集合。
把函数依次作用在list中的每一个元素上,得到一个新的list并返回。map不改变原list,而是返回一个新list。
nums = [1,2,3,4,5]
def square(x):
return x**2
print(list(map(square,nums)))
# [1, 4, 9, 16, 25]
# 使用lambda匿名函数的方法使用map()函数
print(list(map(lambda x:x**2,nums)))
# [1, 4, 9, 16, 25]
# map还可以实现类型转换
print(list(map(int,(1,2,3)))) # [1,2,3]
print(list(map(int,'123'))) # [1,2,3]
print(list(map(int,{"1":11,"2":22,"3":33,}))) # [1,2,3]
lambda:对列表的每个元素进行处理
关于Python中的lambda,这篇阅读量10万+的文章可能是你见过的最完整的讲解
匿名函数,不用函数名。
重点是将lambda函数作为参数传递给其他函数
filter函数。此时lambda函数用于指定过滤列表元素的条件。例如:
filter(lambda x: x % 3 == 0, [1, 2, 3])
# 指定将列表[1,2,3]中能够被3整除的元素过滤出来,
# 其结果是[3]。
sorted函数。此时lambda函数用于指定对列表中所有元素进行排序的准则。例如:
sorted([1, 2, 3, 4, 5, 6, 7, 8, 9], key=lambda x: abs(5-x))
# 将列表[1, 2, 3, 4, 5, 6, 7, 8, 9]按照元素与5距离从小到大进行排序,
# 其结果是[5, 4, 6, 3, 7, 2, 8, 1, 9]。
map函数。此时lambda函数用于指定对列表中每一个元素的共同操作。例如:
map(lambda x: x+1, [1, 2,3])
# 将列表[1, 2, 3]中的元素分别加1,
# 其结果[2, 3, 4]。
reduce函数。此时lambda函数用于指定列表中两两相邻元素的结合条件。例如:
reduce(lambda a, b: '{}, {}'.format(a, b), [1, 2, 3, 4, 5, 6, 7, 8, 9])
# 将列表 [1, 2, 3, 4, 5, 6, 7, 8, 9]中的元素从左往右两两以逗号分隔的字符的形式依次结合起来,
# 其结果是'1, 2, 3, 4, 5, 6, 7, 8, 9'。
filter:从列表中获取符合条件的值
该函数的目的是提取出seq中能使func为true的元素序列。func函数是一个布尔函数,filter()函数调用这个函数一次作用于seq中的每一个元素,筛选出符合条件的元素。
filter(function, iterable)
nums = [x for x in range(10)]
print(list(filter(lambda x:x%2==0,nums))) # 偶数 [0, 2, 4, 6, 8]
print(list(filter(None,nums))) # 大于0的数 [1, 2, 3, 4, 5, 6, 7, 8, 9]
reduce:迭代的对集合的两个元素进行某操作
reduce() 函数会对参数序列中元素进行累积。
函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果
from functools import reduce
# 列表求和
def add(x,y):
return x+y
print(reduce(add,[1,2,3,4,5])) # 15
# 指定多个数的显示格式
print(reduce(lambda a, b: '{}, {}'.format(a, b), [1, 2, 3, 4, 5])) # 1, 2, 3, 4, 5
__repr__和repr()
str和repr的区别
上面的博客写到:str出来的值是给人看的字符串,repr出来的值是给机器看的
print(str("hello")) # hello
print(repr("hello")) # 'hello'
对于下面的类,如果直接打印对象,是无法知道对象的具体属性的,如果我们重写 对象的__repr__方法,则可以打印对象的全部信息。
class Student:
def __init__(self, name, grade, age):
self.name = name
self.grade = grade
self.age = age
class Student1:
def __init__(self, name, grade, age):
self.name = name
self.grade = grade
self.age = age
def __repr__(self):
return repr((self.name, self.grade, self.age))
stu = Student("小明","3年级",9)
print(stu) # <__main__.Student object at 0x000000000282F5C8>
stu1 = Student1("小明","3年级",9)
print(stu1) # ('小明', '3年级', 9)