Python笔记【一】

不知不觉,学习Python这门编程语言好像快1年半(还是很菜),之前学了忘,忘了学,感觉自己总结、笔记做的少;最近工作要写些脚本,就总结下自己学到、用到的部分知识;

个人博客:https://blog.csdn.net/zyooooxie

字符串拼接 join()

最开始接触Python,要拼接字符串用的是 连接符号(+);后面再学习的时候,知道join()方法来更高效,所以就换了;

    def test_1214(self):
        str_abc = '2019-12-14'
        str_b = '2019' + '-' + '12' + '-' + '14'
        str_c = ''.join(['2019', '-', '12', '-', '14'])
        str_d = '-'.join(('2019', '12', '14'))
        print(str_abc)
        print(str_b)
        print(str_c)
        print(str_d)

上面的四种str都是一种格式,‘yyyy-MM-dd’
在这里插入图片描述
我工作中,有些时间是’yyyyMMdd’,但是传参的用的是’yyyy-MM-dd’;
用到join()拼接,可以这样来处理:

    def change_str(self, test_day):
        """
        :param test_day: yyyyMMdd
        :return: yyyy-MM-dd
        """
        return '-'.join((test_day[0:4], test_day[4:6], test_day[-2:])

此外,join() 作用的是 序列

在这里插入图片描述

匿名函数 lambda表达式

lambda表达式语法精简,基本语法是 在冒号(:)左边放参数,【多个参数使用’,'隔开】右边是返回值;

针对刚才所写的方法change_str() ,用lambda表达式,可以这样处理:

    def test_12142(self):
        old = self.change_str('20191214')
        print(old)
        
        f = lambda x, y, z: '-'.join([x, y, z])
        new = f('2019', '12', '16')
        print(new, type(new))

在这里插入图片描述

三元操作符

a = x if 条件 else y
这就是三元操作符的语法;是说 当条件成立、为True的时候,a的赋值为x;不然就赋值为y

    def if_else(self, x, y):
        # abc的赋值
        if x < y:
            abc = x
        else:
            abc = y

        # 条件表达式 简单写
        ABC = x if x < y else y

        print(abc, ABC)

关于三元操作符,有个小提醒:使用的时候,可以加个()

举2个我的例子:

在这里插入图片描述

在这里插入图片描述

map()

map() 会根据提供的函数对指定序列做映射 (在python3中返回迭代器)

  1. map() 这个内置函数 有2个参数,为一个函数 和一个可迭代对象;实际会将可迭代对象的每一个元素作为函数的参数进行加工,直到可迭代对象的每个元素都加工完毕。

假设我手上有个time的list,我要对其每个元素都做加 ‘-’ 的处理,

time_list = ['20191201', '20191202', '20190101', '20190102', '20190201', '20190202', '20190301', '20190302']

用map(),可以这样处理:

    def test_12143b(self):
        # 改变time_list的每个元素
        time_list = ['20191201', '20191202', '20190101', '20190102', '20190201', '20190202', '20190301', '20190302']
        new_list = list(map(self.change_str, time_list))
        print(new_list)

常用匿名函数,就如下:

    def test_12143a(self):
        # 改变time_list的每个元素
        time_list = ['20191201', '20191202', '20190101', '20190102', '20190201', '20190202', '20190301', '20190302']
        new_list = list(map(lambda x: self.change_str(x), time_list))
        print(new_list)

在这里插入图片描述

  1. map() 的第二个参数是收集参数,支持多个迭代对象
    map()会从所有可迭代对象中 依次选取一个元素组成一个元组,然后将元组传递给func。【若多个可迭代对象长度不一致,选择较短的】
x_list = [1, 5, 9, 12]
y_list = [111, 25, 9333, 1.02, 544, 78787]
ABC = list(map(lambda x, y: x + y, x_list, y_list))
print(ABC)
print('a')



x_list = [1, 5, 9, 12] * 2
y_list = [111, 25, 9333, 1.02, 544, 78787]
z_list = [6] * 9
ABC2 = list(map(lambda x, y, z: z + x + y, x_list, y_list, z_list))
print(ABC2)
print('d')
"""
@blog: https://blog.csdn.net/zyooooxie
@qq: 153132336
@wechat: 153132336
"""

# 对于函数的输入已经是参数元组的情况,请参阅itertools.starmap()。

def test_map():
    # map(function, iterable, ...)
    # map 是 返回一个将 function 应用于 iterable 中每一项并输出其结果的迭代器
    a = map(lambda x: x + 33, [1, 2, 3])
    print(a, type(a))  # map object
    print(list(a))

    # 如果传入了额外的 iterable 参数,function 必须接受相同个数的实参并被应用于从所有可迭代对象中并行获取的项。
    # 当有多个可迭代对象时,最短的可迭代对象耗尽则整个迭代就将结束
    b = map(lambda x, y: x + y, [1, 2, 3], [11, 22, 222, 333, 555, 555])
    print(list(b))

# map函数的第一个参数可以是lambda函数也可以是自定义函数,第二个参数是可变参数,可以传入多个可迭代对象。

def test_map_0():
    list_ = [7, 7, 7, 7]
    list_2 = [1, 2, 3, 44, 55, 66, 77, 888]
    abc = map(add, list_, list_2)  # add(a, b)
    Log.info(type(abc))
    Log.info(list(abc))


def test_map_1():
    list_ = [7, -7, -8.5, 8.5, 0]
    abc = map(abs, list_)  # abs(a)
    Log.info(type(abc))
    Log.info(list(abc))


def func_1(str_1, str_2, str_3):
    return ''.join([str_3, str_1, str_2])


def test_map_2():
    list_ = ['abc', '123']
    str_ = 'zyooooxie'
    tuple_ = ('8', '9', '0', '')
    abc = map(func_1, list_, str_, tuple_)
    Log.info(type(abc))
    Log.info(list(abc))


def func_2(*args):
    return ''.join(args)


def test_map_3():
    list_ = ['a', '1']
    str_ = 'zyooooxie'
    tuple_ = ('88', '9', '0000', '', '+-', '*', '//')
    abc = map(func_2, list_, str_, tuple_)
    Log.info(type(abc))
    Log.info(list(abc))

    abc = map(func_2, list_, str_)
    Log.info(type(abc))
    Log.info(list(abc))

    abc = map(func_2, tuple_, str_)
    Log.info(type(abc))
    Log.info(list(abc))

    abc = map(func_2, list_)
    Log.info(type(abc))
    Log.info(list(abc))

filter()

filter() 函数用于过滤序列,过滤掉不符合条件的元素。(Python3 返回一个迭代器对象,如果要转换为列表,可以使用 list() 来转换)

filter() 这个内置函数有2个参数:第一个参数可以是 一个函数【会对第二个可迭代对象里的每一个元素作为 此函数的参数来进行计算,把返回True的值筛选出来】;也可以是None【将第二个参数中 为True的值筛选出来】。

举例 还是那个time的list,我想找出来所有 dd='02’的,用到filter(),可以这样处理:

    def test_12144b(self):
        # 筛选出 time_list中 每个结尾为'02'的元素(组成新list)
        time_list = ['20191201', '20191202', '20190101', '20190102', '20190201', '20190202', '20190301', '20190302']
        new_list = list(filter(lambda x: x[-2:] == '02', time_list))
        print('过滤下', new_list)

        # 对其处理格式,加上 '-'
        last_list = list(map(lambda x: '-'.join((x[0:4], x[4:6], x[-2:])), new_list))
        print('加上 - ', last_list)

如果是不使用匿名函数,要使用条件表达式的话,如下处理:

    def element_end02(self, e):
        return e if e[-2:] == '02' else False

    def test_12144a(self):
        # 筛选出 time_list中 每个结尾为'02'的元素(组成新list)
        time_list = ['20191201', '20191202', '20190101', '20190102', '20190201', '20190202', '20190301', '20190302']
        new_list = list(filter(self.element_end02, time_list))
        print('过滤下', new_list)

        # 对其处理格式,加上 '-'
        last_list = list(map(self.change_str, new_list))
        print('加上 - ', last_list)

在这里插入图片描述

"""
@blog: https://blog.csdn.net/zyooooxie
@qq: 153132336
@wechat: 153132336
"""

def test_filter():
    # filter(function, iterable)
    # 用iterable中 函数function 返回真的那些元素,构建一个新的迭代器。iterable 可以是一个序列,一个支持迭代的容器,或一个迭代器

    test_list = [0, 1, 22, 34, 50, 56, 89, False, True]
    abc = filter(lambda x: x > 50, test_list)
    print(abc)  # filter object
    print(list(abc))

    abc = filter(get_50, test_list)
    print(list(abc))

    # 如果 function 是 None ,则会假设它是一个身份函数,即 iterable 中所有返回假 False 的元素会被移除。
    abc = filter(None, test_list)
    print(list(abc))

    # 请注意,filter(function, iterable) 相当于一个生成器表达式,当function 不是None 的时候为(item for item in iterable if function(item));
    # function 是None 的时候为(item for item in iterable if item) 。

    # 请参阅itertools.filterfalse() 了解,只有function 返回false 时才选取iterable 中元素的补充函数。

    abc = filter(bool, test_list)
    print(list(abc))

列表推导式

列表推导式 是Python提供的一种生成列表的简洁形式。

工作中,在创建list的时候,会常用到:

    def test_c1(self):
        iterable = list((1, 2, 3, 4))
        L = []
        for iter_var in iterable:
            L.append(iter_var + 2)
        print(L)

用上列表推导式,就可以这样处理:

    def test_c2(self):
        iterable = list((1, 2, 3, 4))
        L_new = [i + 2 for i in iterable]
        print(L_new)

执行结果:
在这里插入图片描述

还是拿前面的time的list来说,我想找到每个元素的年份(成一个新list),用列表推导式:

    def test_12145a1(self):
        # 找出time_list的每个元素的年份
        time_list = ['20191201', '20191202', '20190101', '20190102', '20190201', '20190202', '20190301', '20190302']
        new_list = [x[0:4] for x in time_list]
        print(new_list)

用map() + 匿名函数:

    def test_12145a2(self):
        # 找出time_list的每个元素的年份
        time_list = ['20191201', '20191202', '20190101', '20190102', '20190201', '20190202', '20190301', '20190302']
        new_list = list(map(lambda x: x[0:4], time_list))
        print(new_list)

再深入些,我想找的是 dd='01’元素的年份,用列表推导式【 for 循环后面加上 if 判断】:

    def test_12145b1(self):
        # 找出time_list的每个结尾为01元素的 月+天
        time_list = ['20191201', '20191202', '20190101', '20190102', '20190201', '20190202', '20190301', '20190302']
        new_list = [x[4:] for x in time_list if x[-2:] == '01']
        print(new_list)

使用map() 和 filter()

    def test_12145b2(self):
        # 找出time_list的每个结尾为01元素的 月+天
        time_list = ['20191201', '20191202', '20190101', '20190102', '20190201', '20190202', '20190301', '20190302']
        new_list = list(map(lambda x: x[4:] if x[-2:] == '01' else None, time_list))
        print(list(filter(None, new_list)))

在这里插入图片描述

列表推导式、filter()+lambda() 执行速度

某些过滤场景,我会使用filter() 或列表推导式,但一直对这个执行效率比较纠结;

后面自己做了些简单的测试,结论是 列表推导式 会速度更快些。

import datetime

test = range(1000000, 101000000)

t1 = datetime.datetime.now()
print(t1)

# r_1 = list(filter(lambda x: x % 2 == 0, test))          # 1亿 9-10s;2亿 20-22s
# r_2 = [t for t in test if t % 2 == 0]                   # 1亿 6-7s;2亿 13-14s


r3 = list(map(lambda y: y * 2, test))           # 1亿 12s
# r4 = [z * 2 for z in test]                  # 1亿 8s


t2 = datetime.datetime.now()
print(t2)

k = t1 - t2
print(k.microseconds)

装饰器
import datetime
from functools import wraps


def calculate_time(func):
    @wraps(func)
    def inner():
        t1 = datetime.datetime.now()

        func()

        t2 = datetime.datetime.now()
        print((t1 - t2).microseconds, '微秒')

    return inner


test_range = range(1000000, 11000000)


@calculate_time
def test_1():
    abc = list(filter(lambda x: x % 2 == 0, test_range))
    print(abc[-1])


@calculate_time
def test_2():
    abc = [t for t in test_range if t % 2 == 0]
    print(abc[-1])


test_1()
print()
test_2()

在这里插入图片描述

多层表达式

在列表推导式中,也可以用多层 for 循环来生成列表;

    def test_12146a1(self):
        # 全排列
        time_list = ['20191201', '20191202', '20190101', '20190102', '20190201', '20190202', '20190301', '20190302']
        new_list = ['_'.join([x, y]) for x in time_list for y in time_list]
        return new_list

实际就等同:

    def test_12146a2(self):
        # 全排列
        time_list = ['20191201', '20191202', '20190101', '20190102', '20190201', '20190202', '20190301', '20190302']
        new_list = list()
        for x in time_list:
            for y in time_list:
                new_list.append('_'.join([x, y]))
        return new_list

那,这样的表达式 是不是也可以增加if条件:
答案是:Yes

    def test_12146b1(self):
        # 全排列 + if 条件
        time_list = ['20191201', '20191202', '20190101', '20190102', '20190201', '20190202', '20190301', '20190302']
        new = list()
        for x in time_list:
            for y in time_list:
                if x[-2:] == '01' and y[-2:] == '02':
                    new.append('_'.join([x, y]))
        print(new)

    def test_12146b2(self):
        # 全排列 + if 条件
        time_list = ['20191201', '20191202', '20190101', '20190102', '20190201', '20190202', '20190301', '20190302']
        new = list()
        for x in time_list:
            if x[-2:] == '01':
                for y in time_list:
                    if y[-2:] == '02':
                        new.append('_'.join([x, y]))
        print(new)

    def test_12146b3(self):
        # 全排列 + if 条件
        time_list = ['20191201', '20191202', '20190101', '20190102', '20190201', '20190202', '20190301', '20190302']
        new = ['_'.join([x, y]) for x in time_list for y in time_list if x[-2:] == '01' and y[-2:] == '02']
        print(new)

    def test_12146b4(self):
        # 全排列 + if 条件
        time_list = ['20191201', '20191202', '20190101', '20190102', '20190201', '20190202', '20190301', '20190302']
        new = list()
        for x in time_list:
                for y in time_list:
                    if y[-2:] == '02':
                        if x[-2:] == '01':
                            new.append('_'.join([x, y]))
        print(new)

在这里插入图片描述

说这么多,用个真实情景来加深理解:

还是拿time的list来说,我在实际工作时,有时候需要传参-开始时间、结束时间(前提当然是开始时间<=结束时间),我基本是2个for循环,再加个if条件,如果用到多层表达式,可以这样处理:

    def test_12146c(self):
        time_list = ['20191201', '20191202', '20190101', '20190102', '20190201', '20190202', '20190301', '20190302']

        # for a in time_list:
        #     for b in time_list:
        #         if a <= b:
        #             self.examination(account_no, bank, a, b, country)

        fact = [(x, y) for x in time_list for y in time_list if x <= y]
        for f in fact:
            print('开始时间{}、结束时间{}'.format(f[0], f[1]))
            # self.examination(account_no, bank, f[0], f[1], country)

代码中注释的是我真实用的;
用到多层表达式,就把(开始时间、结束时间)重新组成一个list,再对其做个for循环;

上面是说 全排列;可我就想 index相同的元素,进行某些运算呢?

在这里插入图片描述

个人博客 https://blog.csdn.net/zyooooxie

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值