题外话__repr__ //不知道为啥不能直接写,只能在代码处这样写了
定制类
以__包裹的方法称为魔法方法或特殊方法,刚看代码有个地方我不太懂就搜了一下
class User:
def __init__(self, user_id):
self.user_id = user_id
print(User('asd')) #<__main__.User object at 0x000001F24CAF78D0>
class User:
def __init__(self, user_id):
self.user_id = user_id
def __repr__(self):
return 'User({})'.format(self.user_id)
print(User('asd')) #User(asd)
看出区别了吧
1、排序不支持原生比较的对象
内置的 sorted() 函数有一个关键字参数 key ,可以传入一个 callable 对象给它,这个 callable 对象对每个传入的对象返回一个值,这个值会被 sorted 用来排序这些对象
1)
class User:
def __init__(self, user_id):
self.user_id = user_id
def __repr__(self):
return 'User({})'.format(self.user_id)
def sort_notcompare():
users = [User(23), User(3), User(99)]
print(users) #[User(23), User(3), User(99)]
print(sorted(users, key=lambda u: u.user_id)) #[User(3), User(23), User(99)]
2)用operator.attrgetter()代替lambda
from operator import attrgetter
sorted(users, key=attrgetter('user_id')) #[User(3), User(23), User(99)]
attrgetter()和itemgetter()作用于字典很类似
题外话:关于sorted的排序
a = [4,2,3,6,4,4,7,9,6,3,9]
sorted(a) #[2, 3, 3, 4, 4, 4, 6, 6, 7, 9, 9]
sorted(a, reverse=False) #[2, 3, 3, 4, 4, 4, 6, 6, 7, 9, 9]
sorted(a, reverse=True) #[9, 9, 7, 6, 6, 4, 4, 4, 3, 3, 2]
2、通过某个字段将记录分组
对于一个字典,根据某个键来进行分组,可以用到itertools.groupby()函数
rows = [
{'address': '5412 N CLARK', 'date': '07/01/2012'},
{'address': '5148 N CLARK', 'date': '07/04/2012'},
{'address': '5800 E 58TH', 'date': '07/02/2012'},
{'address': '2122 N CLARK', 'date': '07/03/2012'},
{'address': '5645 N RAVENSWOOD', 'date': '07/02/2012'},
{'address': '1060 W ADDISON', 'date': '07/02/2012'},
{'address': '4801 N BROADWAY', 'date': '07/01/2012'},
{'address': '1039 W GRANVILLE', 'date': '07/04/2012'},
]
from operator import itemgetter
rows_date = sorted(rows, key=itemgetter('date'))
#{'address': '5412 N CLARK', 'date': '07/01/2012'}
#{'address': '4801 N BROADWAY', 'date': '07/01/2012'}
#{'address': '5800 E 58TH', 'date': '07/02/2012'}
#{'address': '5645 N RAVENSWOOD', 'date': '07/02/2012'}
#{'address': '1060 W ADDISON', 'date': '07/02/2012'}
#{'address': '2122 N CLARK', 'date': '07/03/2012'}
#{'address': '5148 N CLARK', 'date': '07/04/2012'}
#{'address': '1039 W GRANVILLE', 'date': '07/04/2012'}
from itertools import groupby
rows_group = groupby(rows_date, key=itemgetter('date'))
for date, items in rows_group:
print(date)
for i in items:
print(i)
#07/01/2012
#{'address': '5412 N CLARK', 'date': '07/01/2012'}
#{'address': '4801 N BROADWAY', 'date': '07/01/2012'}
#07/02/2012
#{'address': '5800 E 58TH', 'date': '07/02/2012'}
#{'address': '5645 N RAVENSWOOD', 'date': '07/02/2012'}
#{'address': '1060 W ADDISON', 'date': '07/02/2012'}
#07/03/2012
#{'address': '2122 N CLARK', 'date': '07/03/2012'}
#07/04/2012
#{'address': '5148 N CLARK', 'date': '07/04/2012'}
#{'address': '1039 W GRANVILLE', 'date': '07/04/2012'}
groupby()会扫描整个序列并查找连续相同值(或根据指定key返回值相同)的元素序列,每次返回一个值和一个迭代器,这个迭代器可以生成元素之全部等于上面那个值的组中所有对象,还有一个特别提醒,因为只会对连续的元素进行分组,所以在分组前必须进行排序
rows_group = groupby(rows_date, key=itemgetter('date'))
for date, items in rows_group:
print(date)
for i in items:
print(i)
#07/01/2012
#{'address': '5412 N CLARK', 'date': '07/01/2012'}
#07/04/2012
#{'address': '5148 N CLARK', 'date': '07/04/2012'}
#07/02/2012
#{'address': '5800 E 58TH', 'date': '07/02/2012'}
#07/03/2012
#{'address': '2122 N CLARK', 'date': '07/03/2012'}
#07/02/2012
#{'address': '5645 N RAVENSWOOD', 'date': '07/02/2012'}
#{'address': '1060 W ADDISON', 'date': '07/02/2012'}
#07/01/2012
#{'address': '4801 N BROADWAY', 'date': '07/01/2012'}
#07/04/2012
#{'address': '1039 W GRANVILLE', 'date': '07/04/2012'}
就像这样,没起到分组的作用
3、过滤序列元素
你有一个数据序列,想利用一些规则从中提取出需要的值或者是缩短序列
1)可以使用列表推导
mylist = [1, 4, -5, 10, -7, 2, 3, -1]
a = (n for n in mylist if n>0) #一个迭代器
for i in a:
print(i)
#1
#4
#10
#2
#3
b = [n for n in mylist if n>0]
print(b) #[1, 4, 10, 2, 3],我也搞不懂为啥换成[]就能直接输出
2)如果比较复杂就可以用fliter()
values = ['1', '2', '-3', '-', '4', 'N/A', '5']
def is_int(val):
try:
x = int(val)
return True
except ValueError:
return False
ivals = list(filter(is_int, values))
print(ivals) # ['1', '2', '-3', '4', '5']
关于filter()的使用,看这篇文章
filter()包括两个参数,分别是function和list,根据function返回的结果是否为真来过滤list参数中的项,最后返回一个新列表
注意 filter返回的是一个迭代器,如果想要显示里面的内容,可以用list
values = [1, 2, 3, 4, 5, 6, 7]
new = filter(lambda x:x>4, values)
print(list(new)) #[5, 6, 7]
def func(l):
if l>4:
return True
news = filter(func, values)
print(list(news)) #[5, 6, 7],效果一样
需要注意的是,values是一个列表,进行filter()的时候执行func()传递进去的是values里面的值,而不是把整个列表传进去,如果我这样写
def func(l):
for i in l:
if i>4:
return True
就是以为传进去的内容是列表,这样会报错,这里需多加注意