以下是八个不错的Python技巧,我敢肯定您还没有看到。将这些技巧应用于您的Python代码,使其更简洁,更高效!
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的保证,即排序函数可提供排序稳定性,因此,有一个非常简单的解决方案。这意味着被比较的元素保持其原始顺序。
为了实现按名称和年龄排序,我们可以这样做:
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}
]
名称首先排序,如果名称匹配则对年龄进行排序。因此,所有约翰都按年龄分组。
灵感的来源是StackOverflow的一个问题。
2.列表包含(列表生成器)
列表包含项可以替代用于填充列表的丑陋循环。列表包含的基本语法:
[ expression for item in list if conditional ]
一个用数字序列填充列表的非常简单的示例:
mylist = [i for i in range(10)]
print(mylist)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
而且由于可以使用表达式,所以还可以进行一些数学运算:
squares = [x**2 for x in range(10)]
print(squares)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
甚至调用外部函数:
def some_function(a):
return (a + 5) / 2
my_formula = [some_function(i) for i in range(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 in range(20) if i%2==0]
print(filtered)
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
3.检查对象的内存使用情况
使用sys.getsizeof(),您可以检查对象的内存使用情况:
import sys
mylist = range(0, 10000)
print(sys.getsizeof(mylist))
# 48
哇...等等...为什么这个庞大的列表仅重48个字节?
这是因为range函数返回的类的行为仅类似于列表。范围比实际的数字列表要少得多的内存占用。
您可以自己查看使用列表包含项来创建相同范围内的实际数字列表:
import sys
myreallist = [x for x in range(0, 10000)]
print(sys.getsizeof(myreallist))
# 87632
因此,通过玩弄
sys.getsizeof()
,您可以了解有关Python和内存使用的更多信息。
4.数据类别
从3.7版开始,Python提供了数据类。与常规类或其他替代方法相比有很多优点,例如返回多个值或字典:
- 数据类需要最少的代码
- 您可以比较数据类,因为有
__eq__
- 您可以轻松派生用于调试的数据类,因为
__repr__
- 数据类需要磁带提示,从而减少了出错的机会
这是一个实际使用的数据类的示例:
from dataclasses import dataclass
@dataclass
class Card:
rank: str
suit: str
card = Card("Q", "hearts")
print(card == card)
# True
print(card.rank)
# 'Q'
print(card)
Card(rank='Q', suit='hearts')
详细的指南可以在这里找到。
5.打包属性
除了使用数据类,还可以使用attrs。选择的原因有两个
attrs
:
- 您使用的Python版本早于3.7
- 您想要更多功能
该软件包
attrs
支持所有主要的Python版本,包括CPython 2.7和PyPy。attrs
常规数据类提供的一些其他属性是验证器和转换器。让我们看一个示例代码:
@attrs
class Person(object):
name = attrib(default='John')
surname = attrib(default='Doe')
age = attrib(init=False)
p = Person()
print(p)
p = Person('Bill', 'Gates')
p.age = 60
print(p)
# Output:
# Person(name='John', surname='Doe', age=NOTHING)
# Person(name='Bill', surname='Gates', age=60)
作者
attrs
实际上在介绍数据类的PEP中工作。数据类有意保持简单(易于理解),而attrs提供了您可能需要的一整套功能!
可以在attrs示例页面上找到更多示例。
6.合并字典(Python 3.5+)
从Python 3.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
7.寻找最普遍的价值
要在列表或行中找到最常见的值:
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
-内置列表功能。它接受一个参数,并将计算该参数的出现次数。因此它将test.count(1)
返回2并test.count(4)
返回4。set(test)
返回测试的所有唯一值,所以{1,2,3,4}
因此,在此单行代码中,我们采用了测试的所有唯一值,即相等
{1, 2, 3, 4}
。然后它将max
对它们应用一个函数list.count
并返回最大值。
而且-我没有发明这种单线。
更新:许多评论者正确地指出,有一种更有效的方法可以做到这一点:
from collections import Counter
Counter(test).most_common(1)
# [4: 4]
8.返回多个值
Python中的函数可以返回多个变量,而没有字典,列表或类。它是这样的:
def get_user(id):
# fetch user from database
# ....
return name, birthdate
name, birthdate = get_user(4)
对于有限数量的返回值,这是正常的。但是所有超过3个值的东西都应该放在(data)类中。
通过完成SkillFactory付费在线课程,了解如何从头开始或成为技能和薪资水平升级的热门职业的详细信息:
- Machine Learning (12 )
- Data Science (12 )
- (9 )
- «Python -» (9 )