python cookbook 0807

题外话__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

就是以为传进去的内容是列表,这样会报错,这里需多加注意

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值