当前位置:首页 > 科技  > 软件

Python应知小技巧:如何用更少的代码做更多的事情

来源: 责编: 时间:2023-09-18 21:41:52 212观看
导读Python 是 一种用着很爽的语言。Python也有着很多特性和技巧,可以帮助我们编写更高效、更优雅、更易维护的代码。下面勇哥将介绍一些我常用的Python代码优化的简单小技巧,少写很多代码。短路运算(Short-circuit operatio

Python 是 一种用着很爽的语言。Python也有着很多特性和技巧,可以帮助我们编写更高效、更优雅、更易维护的代码。下面勇哥将介绍一些我常用的Python代码优化的简单小技巧,少写很多代码。aXj28资讯网——每日最新资讯28at.com

aXj28资讯网——每日最新资讯28at.com

短路运算(Short-circuit operation)

咱们都知道,短路运算也就是 ”与 ,或 ,非“ 这几个组成。但是有些时候,我们很多 if-else语句其实可以使用这种短路运算来简写代码的。aXj28资讯网——每日最新资讯28at.com

例, 获取用户信息,不存在的用户则返回匿名用户, 代码:aXj28资讯网——每日最新资讯28at.com

def get_user(user):    # 常规代码    if user:        return user    return "匿名用户"    # 短路来简写代码def get_user(user):    return user or "匿名用户"

使用短路运算处理,那么就只需要一行代码即可,这样写也挺易读的。aXj28资讯网——每日最新资讯28at.com

切片替代循环(Slice)

使用切片代替循环或递归来操作序列。切片是一种用于从一个序列(如字符串、列表、元组等)中获取一部分或全部元素的语法。aXj28资讯网——每日最新资讯28at.com

例,反转数据,代码:aXj28资讯网——每日最新资讯28at.com

# 使用循环def reverse(lst):    new_lst = []    for i in range(len(lst) - 1, -1, -1):        new_lst.append(lst[i])    return new_lstlst = [1, 2, 3, 4, 5]print(reverse(lst)) # [5, 4, 3, 2, 1]# 使用切片def reverse(lst):    return lst[::-1]lst = [1, 2, 3, 4, 5]print(reverse(lst)) # [5, 4, 3, 2, 1]

切片的操作比循环或递归更简单并且高效,因为切片是基于内置函数实现的,而循环或递归是基于自定义函数实现。aXj28资讯网——每日最新资讯28at.com

列表推导式(List Comprehension)

列表推导式是一种用于从一个可迭代对象(如列表、元组、字典、集合等)创建一个新的列表的简洁的语法。aXj28资讯网——每日最新资讯28at.com

例,从一个列表中筛选出所有的偶数,并将它们乘以2,代码:aXj28资讯网——每日最新资讯28at.com

# 使用普通的循环lst = [1, 2, 3, 4, 5, 6]new_lst = []for x in lst:    if x % 2 == 0:        new_lst.append(x * 2)print(new_lst) # [4, 8, 12]
# 使用列表推导式lst = [1, 2, 3, 4, 5, 6]new_lst = [x * 2 for x in lst if x % 2 == 0]print(new_lst) # [4, 8, 12]

一行代码实现循环、条件判断和赋值等操作,提高了代码的可读性和效率,而且运行速度也更快(可以思考一下为什么更快)。aXj28资讯网——每日最新资讯28at.com

生成器表达式(Generator Expression)

生成器表达式是一种类似于列表推导式的语法,但是它不会一次性生成一个完整的列表,而是返回一个生成器对象,可以按需逐个产生元素。aXj28资讯网——每日最新资讯28at.com

例,计算一个列表中所有偶数的平方和,代码:aXj28资讯网——每日最新资讯28at.com

# 使用普通的循环lst = [1, 2, 3, 4, 5, 6]sum = 0for x in lst:    if x % 2 == 0:        sum += x ** 2print(sum) # 56
# 使用生成器表达式lst = [1, 2, 3, 4, 5, 6]sum = sum(x ** 2 for x in lst if x % 2 == 0)print(sum) # 56

这个生成器表达式可以节省内存空间,提高性能,适合处理大量或无限的数据,而且不会占用额外的内存空间,特别适用于读取大批量的数据。当然我们也可以用yeild也能做一个生成器,这个太东西很牛逼。aXj28资讯网——每日最新资讯28at.com

枚举(Enumerate)

枚举是一种用于同时获取可迭代对象中的元素和索引的函数。枚举可以避免使用额外的变量来记录索引,提高了代码的可读性和效率。aXj28资讯网——每日最新资讯28at.com

例,打印一个列表中每个元素及其对应的索引,代码:aXj28资讯网——每日最新资讯28at.com

# 使用普通的循环lst = ["a", "b", "c", "d", "e"]index = 0for x in lst:    print(index, x)    index += 1# 输出:# 0 a# 1 b# 2 c# 3 d# 4 e
# 使用枚举lst = ["a", "b", "c", "d", "e"]for index, x in enumerate(lst):    print(index, x)# 输出:# 0 a# 1 b# 2 c# 3 d# 4 e

使用枚举的代码更加简洁和清晰,而且不需要手动更新索引。aXj28资讯网——每日最新资讯28at.com

三元运算符(Ternary Operator)

三元运算符是一种用于根据一个条件表达式来选择两个不同的值的简洁的语法。aXj28资讯网——每日最新资讯28at.com

例,根据一个数字的正负来赋值一个字符串,代码:aXj28资讯网——每日最新资讯28at.com

# 使用普通的if-else语句num = -5if num > 0:    sign = "positive"else:    sign = "negative"print(sign) # negative
# 使用三元运算符num = -5sign = "positive" if num > 0 else "negative"print(sign) # negative

三元运算符可以用一行代码实现简单的条件判断和赋值,提高了代码的可读性和效率,而且不需要多余的变量和语句。aXj28资讯网——每日最新资讯28at.com

字典处理条件判断

遇到if循环语句很长的时候,其实可以使用字典来替代,两者的执行效率没有试验过,感觉差不了多少。aXj28资讯网——每日最新资讯28at.com

例, 使用字典来判断返回值, 代码:aXj28资讯网——每日最新资讯28at.com

# 使用多个if-elif-else语句def foo(x):    if x == "a":        return 1    elif x == "b":        return 2    elif x == "c":        return 3    else:        return -1print(foo("a")) # 1print(foo("d")) # -1# 使用字典def foo(x):    dic = {"a": 1, "b": 2, "c": 3}    return dic.get(x, -1)print(foo("a")) # 1print(foo("d")) # -1

合理利用字典的get方法,可以减少很多代码的使用。aXj28资讯网——每日最新资讯28at.com

装饰器(Decorator)

装饰器是一种用于在不修改原函数定义和调用的情况下,给函数添加额外的功能或修改其行为的语法。aXj28资讯网——每日最新资讯28at.com

例,给一个函数添加一个计时的功能,记录其运行时间,代码:aXj28资讯网——每日最新资讯28at.com

# 使用普通的函数调用import timedef foo():    # do something    time.sleep(1)start = time.time()foo()end = time.time()print(f"foo() took {end - start} seconds to run.") 
# 使用装饰器import timedef timer(func):    def wrapper(*args, **kwargs):        start = time.time()        result = func(*args, **kwargs)        end = time.time()        print(f"{func.__name__}() took {end - start} seconds to run.")        return result    return wrapper@timer # 相当于 foo = timer(foo)def foo():    # do something    time.sleep(1)foo() 

装饰器能做的事太多了,比如flask 框架,真尼玛装饰器用到飞天。勇哥也就一般用于实现一些通用的功能,如日志、缓存、计时、权限检查等,让代码可复用更强一写。aXj28资讯网——每日最新资讯28at.com

上下文管理器(Context Manager)

上下文管理器是一种用于在执行某些操作之前和之后自动执行一些预设的操作的语法。上下文管理器可以用于实现一些资源管理的功能,aXj28资讯网——每日最新资讯28at.com

例如,打开一个文件,读取其内容,并在完成后自动关闭文件,代码:aXj28资讯网——每日最新资讯28at.com

# 使用普通的try-finally语句file = open("test.txt", "r")try:    content = file.read()    print(content)finally:    file.close()
# 使用上下文管理器with open("test.txt", "r") as file:    content = file.read()    print(content)

使用上下文管理器我们一般用于 打开和关闭文件、获取和释放锁、连接和断开数据库等。代码的安全性问题和可读性也很好处理。aXj28资讯网——每日最新资讯28at.com

Lambda 表达式(Lambda Expression)

lambda表达式(代替简单的函数定义来创建匿名函数。lambda表达式是一种用于定义一个只有一行代码的函数的简洁的语法。aXj28资讯网——每日最新资讯28at.com

例,处理排序sorted,指定字段,代码:aXj28资讯网——每日最新资讯28at.com

lst = [9,2,3,4,5,5,1,2,3]# 不使用lambda表达式def add(item):   return itemprint(sorted(add, item))# 使用lambda表达式print(sorted(lst, key=lambda x:x))

lambda表达式我们一般用来实现一些简单的功能,如排序、过滤、映射等。使用匿名函数,代码有时候少写一些外,还有一点就是 lambda 表达式用完就会在内存中舍弃,也挺好。aXj28资讯网——每日最新资讯28at.com

map 函数

map函数代替循环来对可迭代对象中的每个元素应用一个函数。map函数是一种用于将一个函数作用于一个可迭代对象中的每个元素,并返回一个新的可迭代对象的函数。aXj28资讯网——每日最新资讯28at.com

例,将一批字符列表字符串转数字列表,代码:aXj28资讯网——每日最新资讯28at.com

# 不使用map函数lst = ["1", "2", "3", "4", "5"]new_lst = []for x in lst:    new_lst.append(int(x))print(new_lst) # [1, 2, 3, 4, 5]# 使用map函数lst = ["1", "2", "3", "4", "5"]new_lst = list(map(int, lst))print(new_lst) # [1, 2, 3, 4, 5]

是不是看起来代码又少了很多,而且这种内置函数,一般速度都比咱们自己写的代码运行效率高,基于这个强大的高阶函数,我们可以用来实现一些批量处理的功能,如类型转换、格式化、计算,数据合并等。aXj28资讯网——每日最新资讯28at.com

filter 函数

filter函数代替循环来从可迭代对象中筛选出满足一个条件的元素。filter函数是一种用于将一个条件函数作用于一个可迭代对象中的每个元素,并返回一个只包含满足条件元素的新的可迭代对象的函数。aXj28资讯网——每日最新资讯28at.com

例,从一个列表中挑选符合要求的数据出来组成另一个列表,代码:aXj28资讯网——每日最新资讯28at.com

# 不使用filter函数lst = [1, 2, 3, 4, 5]new_lst = []for x in lst:    if x % 2 == 0:        new_lst.append(x)print(new_lst) # [2, 4]# 使用filter函数lst = [1, 2, 3, 4, 5]new_lst = list(filter(lambda x: x % 2 == 0, lst))print(new_lst) # [2, 4]

filter函数可以用于实现一些筛选和过滤的功能,如删除空值、去重、选择子集等,也是一个很牛的高阶函数。aXj28资讯网——每日最新资讯28at.com

@properyt 装饰器

@property 装饰器有些时候可以用来替代 geter和setter 方法来管理类书信。这个装饰器装饰的函数会转为一个属性的语法,可以在访问和修改属性的时候,执行一些额外的操作,不用显式调用。aXj28资讯网——每日最新资讯28at.com

例,对类属性的修改与获取, 代码:aXj28资讯网——每日最新资讯28at.com

# 不使用@property装饰器class Person:   def __init__(self, name, age):       self.name = name       self.age = age   def get_name(self):       return self.name   def set_name(self, name):       if not isinstance(name, str):           raise TypeError("name must be a string")       self.name = name   def get_age(self):       return self.age   def set_age(self, age):       if not isinstance(age, int):           raise TypeError("age must be an integer")       if age < 0 or age > 150:           raise ValueError("age must be between 0 and 150")       self.age = agep = Person("kira", 40) # 实例化print(p.get_name()) # kiraprint(p.get_age()) # 40p.set_name("勇哥")p.set_age(35)print(p.get_name()) # 勇哥print(p.get_age()) # 35# 使用@property装饰器class Person:   def __init__(self, name, age):       self._name = name       self._age = age   @property   def name(self):       return self._name   @name.setter   def name(self, name):       if not isinstance(name, str):           raise TypeError("name must be a string")       self._name = name   @property   def age(self):       return self._age   @age.setter   def age(self, age):       if not isinstance(age, int):           raise TypeError("age must be an integer")       if age < 0 or age > 150:           raise ValueError("age must be between 0 and 150")       self._age = agep = Person("kira", 30)print(p.name) # kiraprint(p.age) # 30p.name = "勇哥"p.age = 35print(p.name) # 勇哥print(p.age) # 35

从上面的代码,我们就可以了解到@property 可以做的事就很多了,比如实现属性管理,数据验证,类型转换,缓存... 可读性和安全性也不错.aXj28资讯网——每日最新资讯28at.com

slots属性

来到本文的最后一个要分享的 __slots__ 属性,这个事用来指定一个类可以有那些属性的语法,可以用来替代一下__dict__ 来节省类的内存空间,因为他避免了给每个实例创建一个 __dict__ 属性来存储所有属性和值。一般用于内存优化。aXj28资讯网——每日最新资讯28at.com

例,指定一个类实例时只有指定的属性,代码:aXj28资讯网——每日最新资讯28at.com

# 不使用__slots__属性class Person:   def __init__(self, name, age):       self.name = name       self.age = agep = Person("勇哥", 90)print(p.__dict__) print(p.__sizeof__()) 

输出:aXj28资讯网——每日最新资讯28at.com

{'name': '测试玩家勇哥', 'age': 90}32
# 使用__slots__属性class Person:    # 指定该类只能拥有name和age两个属性    __slots__ = ("name", "age")    def __init__(self, name, age):        self.name = name        self.age = agep = Person("Alice", 20)print(p.__sizeof__()) print(p.__dict__) 

输出:aXj28资讯网——每日最新资讯28at.com

Traceback (most recent call last): File "D:/app/apitest/debug/ts.py", line 82, in <module>   print(p.__dict__) # AttributeError: 'Person' object has no attribute '__dict__'AttributeError: 'Person' object has no attribute '__dict__'32

很明显,这个类已经没有了__dict__属性了,也就是可以减少内存占用,提高访问速度这种玩意,但是也有不好的地方,比如不能多重继承了,也不能添加新属性。要打印出来你限制的属性也就只能dir 或者 getter来获取了。总之小伙伴们看着使用吧。aXj28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-10472-0.htmlPython应知小技巧:如何用更少的代码做更多的事情

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 使用上 Spring 的事件机制,真香!

下一篇: 利用开放接口,如何一步步打造自己的独特图片网站

标签:
  • 热门焦点
  • 5月iOS设备性能榜:M1 M2依旧是榜单前五

    5月iOS设备性能榜:M1 M2依旧是榜单前五

    和上个月一样,没有新品发布的iOS设备性能榜的上榜设备并没有什么更替,仅仅只有跑分变化而产生的排名变动,刚刚开始的苹果WWDC2023,推出的产品也依旧是新款Mac Pro、新款Mac Stu
  • 女孩租房开2小时空调用完100元电费引热议:5级能耗惹不起 月薪过万电费也交不起

    女孩租房开2小时空调用完100元电费引热议:5级能耗惹不起 月薪过万电费也交不起

    近日,江苏苏州一女孩租房当天充值了100元电费,开着空调不到2小时发现电费已用完。对于为什么这个快,房东表示,电表坏了这种情况很多,之前也遇到过,给租客换
  • 虚拟键盘 API 的妙用

    虚拟键盘 API 的妙用

    你是否在遇到过这样的问题:移动设备上有一个固定元素,当激活虚拟键盘时,该元素被隐藏在了键盘下方?多年来,这一直是 Web 上的默认行为,在本文中,我们将探讨这个问题、为什么会发生
  • 为什么你不应该使用Div作为可点击元素

    为什么你不应该使用Div作为可点击元素

    按钮是为任何网络应用程序提供交互性的最常见方式。但我们经常倾向于使用其他HTML元素,如 div span 等作为 clickable 元素。但通过这样做,我们错过了许多内置浏览器的功能。
  • 每天一道面试题-CPU伪共享

    每天一道面试题-CPU伪共享

    前言:了不起:又到了每天一到面试题的时候了!学弟,最近学习的怎么样啊 了不起学弟:最近学习的还不错,每天都在学习,每天都在进步! 了不起:那你最近学习的什么呢? 了不起学弟:最近在学习C
  • 携众多高端产品亮相ChinaJoy,小米带来一场科技与人文的视听盛宴

    携众多高端产品亮相ChinaJoy,小米带来一场科技与人文的视听盛宴

    7月28日,全球数字娱乐领域最具知名度与影响力的年度盛会中国国际数码互动娱乐展览会(简称ChinaJoy)在上海新国际博览中心盛大开幕。作为全球领先的科
  • 2纳米决战2025

    2纳米决战2025

    集微网报道 从三强争霸到四雄逐鹿,2nm的厮杀声已然隐约传来。无论是老牌劲旅台积电、三星,还是誓言重回先进制程领先地位的英特尔,甚至初成立不久的新
  • 电博会与软博会实现

    电博会与软博会实现"线下+云端"的双线融合

    在本次“电博会”与“软博会”双展会利好条件的加持下,既可以发挥展会拉动人流、信息流、资金流实现快速交互流动的作用,继而推动区域经济良性发展;又可以聚
  • “买真退假” 这种“羊毛”不能薅

    “买真退假” 这种“羊毛”不能薅

    □ 法治日报 记者 王春   □ 本报通讯员 胡佳丽  2020年初,还在上大学的小东加入了一个大学生兼职QQ群。群主&ldquo;七王&rdquo;在群里介绍一些刷单赚
Top