本文将介绍15个简洁的Python技巧,向着简洁更高效,学习易懂出发。

目录

  • 1.通过多个键值将对象进行排序
  • 2.数据类别
  • 3.列表推导
  • 4.检查对象的内存使用情况
  • 5.查找最频繁出现的值
  • 6.属性包
  • 7.合并字典(Python3.5+)
  • 8.返回多个值
  • 9.列表元素的过滤
    • filter()的使用
  • 10.修改列表
    • map()的使用
  • 11.利用zip()来组合列表
  • 12.颠倒列表
  • 13.检查列表中元素的存在情况
  • 14.展平嵌套列表
  • 15.检查唯一性

1.通过多个键值将对象进行排序

假设要对以下字典列表进行排序:

people = [
{ 'name': 'John', "age": 64 },
{ 'name': 'Janet', "age": 34 },
{ 'name': 'Ed', "age": 24 },
{ 'name': 'Sara', "age": 64 },
{ 'name': 'John', "age": 32 },
{ 'name': 'Jane', "age": 34 },
{ 'name': 'John', "age": 99 },
]

不仅要按名字或年龄对其进行排序,还要将两个字段同时进行排序。在SQL中,会是这样的查询:

SELECT * FROM people ORDER by name, age

实际上,这个问题的解决方法可以非常简单,Python保证sort函数提供了稳定的排序顺序,这也意味着比较相似的项将保留其原始顺序。要实现按名字和年龄排序,可以这样做:

import operator
people.sort(key=operator.itemgetter('age'))
people.sort(key=operator.itemgetter('name'))

要注意如何反转顺序。首先按年龄分类,然后按名字分类,使用operator.itemgetter()从列表中的每个字典中获取年龄和名字字段,这样你就会得到想要的结果:

[
{'name': 'Ed', 'age': 24},
{'name': 'Jane', 'age': 34},
{'name': 'Janet','age': 34},
{'name': 'John', 'age': 32},
{'name': 'John', 'age': 64},
{'name': 'John', 'age': 99},
{'name': 'Sara', 'age': 64}
]

名字是主要排序项,如果姓名相同,则以年龄排序。因此,所有John都按年龄分组在一起。

2.数据类别

自3.7版之后,Python开始能提供数据类别。比起常规类或其他替代方法(如返回多个值或字典),它有着更多优点:

  1. 数据类需要很少的代码
  2. 可以比较数据类,因为 eq 可以实现此功能
  3. 数据类需要类型提示,减少了发生错误的可能性
  4. 可以轻松打印数据类以进行调试,因为__repr__可以实现此功能

这是一个工作中的数据类示例:

from dataclasses import dataclass @dataclassclassCard: rank: strsuit: strcard=Card("Q", "hearts") print(card == card) # True print(card.rank) # 'Q' print(card) Card(rank='Q', suit='hearts')

3.列表推导

列表推导可以在列表填写里代替讨厌的循环,其基本语法为

[ expression for item in list if conditional ]

来看一个非常基本的示例,用数字序列填充列表:

mylist = [i for i inrange(10)] print(mylist) # [0, 1, 2, 3,4, 5, 6, 7, 8, 9]

因为可以使用表达式,所以你还可以进行一些数学运算:

squares = [x**2for x inrange(10)] print(squares) # [0, 1, 4, 9,16, 25, 36, 49, 64, 81]

甚至能调用外部函数:

defsome_function(a): return (a +5) /2my_formula= [some_function(i) for i inrange(10)] print(my_formula) # [2.5, 3.0,3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0]

最后,可以使用if函数来筛选列表。在这种情况下,只保留可被2除的值:

filtered = [i for i inrange(20) if i%2==0] print(filtered) # [0, 2, 4, 6,8, 10, 12, 14, 16, 18]

4.检查对象的内存使用情况

使用sys.getsizeof()可以检查对象的内存使用情况:

import sys mylist =range(0, 10000) print(sys.getsizeof(mylist)) # 48

为什么这个庞大的列表只有48个字节呢,这是因为range函数返回的类表现为列表。与使用实际的数字列表相比,数序列的存储效率要高得多。我们可以通过列表推导来创建相同范围内的实际数字列表:

import sys myreallist = [x for x inrange(0, 10000)] print(sys.getsizeof(myreallist)) # 87632

通过使用sys.getsizeof(),我们可以了解更多关于Python和内存使用情况的信息。

5.查找最频繁出现的值

要查找列表或字符串中最频繁出现的值:

test = [1, 2, 3, 4, 2, 2, 3, 1, 4, 4, 4] print(max(set(test), key = test.count)) # 4
  • max()将返回列表中的最大值。key参数采用单个参数函数自定义排序顺序,在本例中为test.count,该函数适用于迭代器上的每个项目。
  • test.count是list的内置功能。它接受一个参数,并计算该参数的出现次数。因此test.count(1)将返回2,而test.count(4)将返回4。
  • set(test)返回test中的所有唯一值,所以{1、2、3、4}

那么在这一行代码将接受test的所有唯一值,即{1、2、3、4}。接下来,max将对其应用list.count 函数并返回最大值。

还有一种更有效的方法:

from collections import Counter
Counter(test).most_common(1)
# [4: 4]

6.属性包

你可以使用attrs代替数据类,选择attrs有两个原因:

  1. 使用的Python版本高于3.7
  2. 想要更多功能

Theattrs软件包支持所有主流Python版本,包括CPython 2.7和PyPy。一些attrs可以提供验证器和转换器这种超常规数据类。来看一些示例代码:

@attrsclassPerson(object): name =attrib(default='John') surname =attrib(default='Doe') age =attrib(init=False) p =Person() print(p) p=Person('Bill', 'Gates') p.age=60print(p) # Output: # Person(name='John', surname='Doe',age=NOTHING) # Person(name='Bill', surname='Gates', age=60)

实际上,attrs的作者已经在使用引入数据类的PEP了。数据类被有意地保持得更简单、更容易理解,而attrs 提供了可能需要的所有特性。

7.合并字典(Python3.5+)

dict1 = { 'a': 1, 'b': 2 } dict2= { 'b': 3, 'c': 4 } merged= { **dict1, **dict2 } print (merged) # {'a': 1, 'b':3, 'c': 4}

如果有重叠的键,第一个字典中的键将被覆盖。在Python 3.9中,合并字典变得更加简洁。上面Python 3.9中的合并可以重写为:

merged = dict1 | dict2

8.返回多个值

Python中的函数在没有字典,列表和类的情况下可以返回多个变量,它的工作方式如下:

defget_user(id): # fetch user from database # .... return name, birthdate name, birthdate =get_user(4)

这是有限的返回值,但任何超过3个值的内容都应放入一个(数据)类。

9.列表元素的过滤

filter()的使用

filter()函数接受2个参数:

  1. 函数对象
  2. 可迭代的对象

接下来我们定义1个函数然后对1个列表进行过滤。

首先我们创建1个列表,并且剔除掉小于等于3的元素:

original_list = [ 1,2,3,4,5]#定义列表#定义过滤函数
4 def filter_three(number):5return number > 3filtered = filter(filter_three, original_list)
filtered_list = list(filtered)
filtered_list#[4,5]

我们定义了列表original_list接着我们定义了一个接受数值型参数number的函数filter_three,当传入的参数值大于3时会返回True,反之则会返回False我们定义了filter对象filtered,其中filter()接受的第一个参数是函数对象,第二个参数是列表对象最终我们将filter对象转化为列表,最终得到经filter_three过滤后original_list内留下的元素。

类似的,我们也可以利用列表推导式来过滤列表元素,作为一种生成和修改列表优雅的方式,下面是使用列表推导完成同样任务的过程:

original_list = [1,2,3,4,5]2
filtered_list = [ number for number in original_list if number > 3]#在列表推导过程中引入条件判断
print(filtered_list)#[4,5]

10.修改列表

map()的使用

Python中内置的map()函数使得我们可以将某个函数应用到可迭代对象内每一个元素之上。

比方说我们想获取到一个列表对象中每一个元素的平方,就可以使用到map()函数,就像下面的例子一样:

original_list = [1,2,3,4,5]
def square( number):return number **2
squares =map(square, original_list)
squares_list = list( squares)
print(squares_list) #[1,4,9,16,25]

类似filter()的工作过程,下面我们来看看发生了什么:

首先我们定义了列表original_list,以及接受数值型参数并返回其平方值的函数square()接着我们定义了map对象squares,类似filter(),map()接受的第一个参数是函数对象,第二个参数是列表对象最终我们将map对象squares列表化,就得到了想要的结果。

同样的我们也可以使用列表推导式完成同样的任务:

original_list = [1,2,3,4,5]
squares_list = [number ** 2for number in original_list]
print(squares_list)#[1,4,9, 16,25]

11.利用zip()来组合列表

有些情况下我们需要将两个或以上数量的列表组合在一起,这类需求使用zip()来完成非常方便。
zip()函数接收多个列表作为参数传入,进而得到每个位置上一一对应的元素组合,就像下面的例子一样:

numbers = [ 1,2,3]
letters = [ 'a', 'b', 'c']
combined = zip(numbers,letters)
combined_list = list( combined)
print(combined_list)
for item in zip( numbers,letters ):print(item[0], '\t', item[1])#[(1,'a'),(2,'b'),(3, 'c')]
#1        a
#2        b
#3        c

12.颠倒列表

Python中的列表是有序的数据结构,正因如此,列表中元素的顺序很重要,有些时候我们需要翻转列表中所有元素的顺序,可以通过Python中的切片操作,用::-1来快捷地实现:

original_list = [1,2,3,4,5]reversed_list = original_list[ : : -1]print('翻转前: ', original_list)
print('翻转后:', reversed_list)#翻转前:[ 1,2,3,4,5]
#翻转后:[5,4,3,2,1]

13.检查列表中元素的存在情况

有些情况下我们想要检查列表中是否存在某个元素,这种时候就可以使用到Python中的in运算符,譬如说我们有一个记录了所有比赛获胜队伍名称的列表,当我们想查询某个队名是否已获胜时,可以像下面的例子一样:

games = [ 'Yankees ', 'Yankees ', 'Cubs ', 'Blue Jays ', 'Giants ']
def isin(item,list_name) :if item in list_name: print(f"{item} is in the list! ")else: print(f"{item} is not in the list! ")isin( 'Blue Jays ' , games)
isin( ' Angels', games)#Blue Jays is in the list!
#Angels is not in the list!

14.展平嵌套列表

有些情况下我们会遇到一些嵌套的列表,其每个元素又是各自不同的列表,这种时候我们就可以利用列表推导式来把这种嵌套列表展平,如下面2层嵌套的例子:

nested_list = [[1,2,3],[4,5,6],[7,8,9]]flat_list = [i for j in nested_list for i in j]print(flat_list)#[1,2,3,4,5,6,7,8,9]

额外补充:

这里只考虑到两层嵌套的列表,如果是更多层嵌套,就需要有多少层写多少for循环,比较麻烦,其实还有一种更好的方法,我们可以使用pip install dm-tree来安装tree这个专门用于展平嵌套结构的库,可以展平任意层嵌套列表,使用例子如下:

import treenested_list_2d = [[1,2,3],[4,5,6],[7,8,9]]nested_list_3d = [[[1,2],[3,4]],[[5,6],[7,8]],[[9,10],[11,12]]]print(tree.flatten(nested_list_2d))
print(tree.flatten(nested_list_3d))#[1,2,3,4,5,6,7,8,9]
#[1,2,3,4,5,6,7,,8, 9, 10, 11,12]

15.检查唯一性

如果你想要查看列表中的值是否都是唯一值,可以使用Python中的set数据结构的特点,譬如下面的例子:

list1 = [ 1,2,3,4,5]
list2 = [1,1,2,3,4]def isunique( 1):if len(l) == len(set(l)) :print( 唯一! ')eise: print(('不唯—! ')isunique( list1)
isunique(list2)#唯—!
#不唯—!

点击领取

经验丰富程序员才知道的15种高级Python小技巧相关推荐

  1. python大型项目经验_经验丰富程序员才知道的8种高级Python技巧

    全文共2330字,预计学习时长11分钟 图源:unsplash 本文将介绍8个简洁的Python技巧,若非经验十足的程序员,你肯定有些从未见过.向着更简洁更高效,出发吧! 1.通过多个键值将对象进行排 ...

  2. 资深程序员才知道的30个Python技巧

    Python中的省略号 Python省略号是三点序列,通常在自然语言中使用.但是您可能不知道的是,这也是Python中的有效对象: - Ellipsis 它主要用于NumPy中的矩阵切片操作.但是,您 ...

  3. 老鸟程序员才知道的40个小技巧

    1.重构是程序员的主力技能. 2.工作日志能提升脑容量. 3.先用profiler调查,才有脸谈优化. 4.注释贵精不贵多.杜绝大姨妈般的"例注".漫山遍野的碎碎念注释,实际就是背 ...

  4. 有什么事是你当了程序员才知道的? | 每日趣闻

    戳一戳小程序查看更多! 往 期 趣 闻 ☞人间真实!如果我有这套装备,我也能码到凌晨...... | 每日趣闻 ☞我酸了~腾讯员工平均月薪 7.6 万 | 每日趣闻 ☞光棍节刚过,你脱单了吗?| 每日 ...

  5. Python 程序员需要知道的 30 个技巧(转载)

    Python 程序员需要知道的 30 个技巧 原创2017-04-14 伯乐专栏/阿喵 Python开发者 Python开发者 Python开发者 微信号 PythonCoder 功能介绍 人生苦短, ...

  6. [转]读《程序员应该知道的97件事》

    正文之前 熟知软件开发的人都知道这个行业里充满了一次次悲壮的失败,每一座成功项目的丰碑下都埋葬着无数同类型的失败项目.大多数软件项目都像是一次典型的死亡行军 加班是一种习惯,并会逐渐产生依赖 编程远远 ...

  7. 程序员应该知道的97件事

     转自:http://dearymz.blog.163.com/blog/static/205657420139243750104/ 正文之前 熟知软件开发的人都知道这个行业里充满了一次次悲壮的失 ...

  8. 读《程序员应该知道的97件事》

    原文链接:http://dearymz.blog.163.com/blog/static/205657420139243750104/ 正文之前 熟知软件开发的人都知道这个行业里充满了一次次悲壮的失败 ...

  9. 《程序员应该知道的97件事》即将上市

    一.出版信息 [书名]程序员应该知道的97件事 [作者]Kevlin Henney  著 [译者]李军 译 吕骏审校 [出版社]电子工业出版社 [书号]978-7-121-11756-5 [定价]45 ...

最新文章

  1. ActionBar右边菜单按钮的添加
  2. linux下phpMyAdmin泛起1045 - Access denied for 的措置
  3. 胡正是什么lisp_《亲爱的挚爱的》演员公开,吴白还是胡一天,grunt却换了人
  4. 白话Elasticsearch40-深入聚合数据分析之案例实战_Global Aggregation:单个品牌与所有品牌平均价格对比
  5. CodeFrist基础_迁移更新数据
  6. typescript函数使用
  7. LuckyDraw app被评为Microsoft365 App Award
  8. python系统状态_python实现系统状态监测和故障转移实例方法
  9. 我是如何用6个月,从0编程经验变成数据科学家的?
  10. 讨论群问题:Linux 下的批量操作,第2种很赞
  11. css3中transform属性及用法
  12. rhel-server-7.2-x86_64无法联网(VMware环境)
  13. CCS中的cmd命令文件
  14. 《计算机网络》学习笔记 ·002【物理层】
  15. 《Effective C#》Item 7:推荐使用不可改变的原子值类型
  16. 2016年3例严重工控安全事故经验教训总结
  17. 南洋oj 题目144小珂的苦恼
  18. getX,getRawX,getWidth,getTranslationX等的区别
  19. (附源码)计算机毕业设计ssm房屋租赁管理系统
  20. 计算机主板故障检测维修,主板故障!教你如何用主板诊断卡检测维修电脑主板故障...

热门文章

  1. SVM原理详细图文教程来了!一行代码自动选择核函数,还有模型实用工具
  2. 计算机界最大“追书坑”,82岁大神高德纳仍在写《计算机程序设计艺术》4B卷...
  3. 反应器(Reactor)模式-golang探索
  4. 正则表达式匹配单个字符(.、[]、\d、\D、\s、\S、\w、\W)
  5. 后退N帧协议中的滑动窗口
  6. MATLAB_8-边缘检测_黄晓明圈出人脸
  7. 网络工程师_想要记录下来的一些题_1
  8. 数据维度爆炸怎么办?详解 5 大常用的特征选择方法
  9. 2022 年计算机视觉的三大趋势
  10. Python 图像处理简介——色彩阴影调整