社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

10 个 Python 秘诀将颠覆你的编码方式

数据STUDIO • 5 月前 • 184 次点击  


通过一些实用技巧和方法,充分发挥Python的强大功能

对于大多数人来说,学习Python编程最初都有一定困难。它看似晦涩难懂,以至于有人甚至怀疑自己是否还需要继续使用Excel这种传统数据分析工具。

然而,只要持之以恒、循序渐进地学习,Python的门径终将为你打开。我就是靠着坚持不懈,不断吸收新知识,最终获得了第一份编程工作。从那时起,我在每一份工作中都能"取之不尽、用之不竭",汲取到各种实用技巧和窍门。今天,就让我分享其中一些精华,希望能为你的Python编程之路提供启迪。

秘诀 1:zip函数

zip函数堪称Python中的利器。它能将多个可迭代对象并行合并为一个可迭代的元组序列,大大简化了对多个序列的遍历操作。这一技巧让我彻底告别了那些冗长、嵌套的循环,代码变得更加简洁可读。

示例

我记得我需要将两个列表中的姓名和年龄配对起来。在使用 zip 之前,我的代码充满了索引变量,难以理解。

names = ["Alice""Bob""Charlie"]
ages = [253035]

for i in range(len(names)):
    print(f"{names[i]} is {ages[i]} years old")

下面是 zip 的简化过程:

names = ["Alice""Bob""Charlie"]
ages = [253035]

# 使用 zip 并行遍历两个列表
for name, age in zip(names, ages):
    print(f"{name} is {age} years old")

这让我的代码更简洁,也更容易阅读。无论何时您需要同时处理多个序列,zip 都是您的好朋友。在你的项目中试试吧,看看你的代码会变得多么简单!

秘诀 2:华勒斯运算符 (:=)

华勒斯运算符(:=)为我拓展了全新的编码视野。它允许在表达式中完成变量赋值,使得求值和赋值合二为一,使代码更加紧凑简练。

示例

我以前编写的代码是在一个循环中读取用户输入,直到他们输入一个有效值。以前的方法是重复性的:

while True:
    user_input = input("Enter a number: ")
    if user_input.isdigit():
        number = int(user_input)
        break

有了海象操作器,代码变得更加简洁:

while (user_input := input("Enter a number: ")).isdigit() == False:
    print("Invalid input, please enter a number.")

number = int(user_input)

这个小技巧让我的循环变得更简单、更容易掌握。在类似情况下,请尝试使用华勒斯运算符(:=)来简化代码!

秘诀 3:集合操作

集合这一数据结构给我留下了深刻印象。作为独特的无序集合,它支持数学运算如并集、交集和差集等操作。集合可高效处理唯一元素,简化复杂的集合论问题。

示例

我记得在一个项目中,我需要找到两个列表中共同的项目和每个列表中唯一的项目。

list1 = [12345]
list2 = [45678]

# 查找共同元素
common_elements = []
for item in list1:
    if item in list2:
        common_elements.append(item)
print(f"common elements: {common_elements}")

# 在 list1 中查找唯一元素
unique_to_list1 = []
for item in list1:
    if item not in list2:
        unique_to_list1.append(item)
print(f "Unique to list1: {unique_to_list1}")

# 查找所有唯一元素
all_unique_elements = list1.copy()
for item in list2:
    if item not in all_unique_elements:
        all_unique_elements.append(item)
print(f"All unique elements: {all_unique_elements}")

使用成套工具使这项工作变得更加容易:

list1 = [12345]
list2 = [45678]

# 将列表转换为集合
set1 = set(list1)
set2 = set(list2)

# 找出交集(共同元素)
common_elements = set1 & set2
print(f "common elements: {common_elements}")

# 找出差异(set1 中的唯一元素)
unique_too_set1 = set1 - set2
print(f "Unique to set1: {unique_too_set1}")

# 找出联合(所有唯一元素)
all_unique_elements = set1 | set2
print(f"All unique elements: {all_unique_elements}")

使用集合可以让代码更高效、更易懂。无论何时需要处理唯一元素或执行集合操作,都可以试试 Python 集合!

秘诀 4:使用 * 解包

解包操作 * 无疑是提高编码效率的秘诀之一。它能将可迭代对象解包为函数的单个参数或变量赋值目标,赋予代码更强的灵活性和可读性。

示例

我曾为需要多个参数的函数而苦恼。

# 定义一个接收多个参数的函数
def greet(first, second, third)
    print(f "Hello {first}, {second}, and {third}!")

# 列出名字
names = ["Alice", "Bob", "Charlie"] # 从列表中手动传递参数

# 从列表中手动传递参数
greet(names[0], names[1], names[2])

手动管理这些参数非常麻烦。后来我发现了解包:

# 定义一个接收多个参数的函数
def greet(first, second, third):
    print(f "Hello {first}, {second}, and {third}!")

# 列出名字
names = ["Alice""Bob""Charlie"# 将列表解压缩为函数参数

# 将列表解压缩为函数参数
greet(*names)

使用 * 进行解包后,我的函数调用和赋值变得更加简单和干净。这一小小的改变对代码的可读性有很大的影响。

秘诀 5:dataclasses 模块

dataclasses 模块为我带来了全新的类编程体验。它能自动创建类实例,无需手动编写__init__方法,极大简化了类的定义和维护。

示例

我以前写过很多重复的代码来初始化类的属性。这既乏味又容易出错。后来我发现了 dataclasses

from dataclasses import dataclass

# 定义一个简单的数据类
@dataclass
class Person
    name:
 str
    age: int
    city: str

# 创建该类的实例
person = Person(name="Alice", age=30, city="New York")

print(person)

在使用 dataclasses 之前,我的代码中充斥着大量的模板:

class Person:
    def __init__(self, name, age, city):
        self.name = name
        self.age = age
        self.city = city

person = Person(name="Alice", age=30, city="New York")
print(person)

使用 dataclasses 使我的代码更简洁、更易于维护。如果您需要处理大量的类定义,不妨试试 dataclasses。它将为你节省时间,并保持代码库的整洁!

秘诀 6:functools.lru_cache 装饰器

functools.lru_cache装饰器可谓是破解性能瓶颈的法宝。它为函数添加了缓存功能,存储计算耗费的函数调用结果,提高了具有相同输入的重复调用效率。

示例

我记得在做一个需要大量计算的项目时,重复计算拖慢了一切。发现了 lru_cache 后,我就像捡到了救命稻草:

from functools import lru_cache

# 定义一个计算量很大的函数
@lru_cache(maxsize=100)
def expensive_function(n):
    print(f"Computing {n}...")
    return n * n

# 多次调用函数
print(expensive_function(4))
print(expensive_function(4))  # This call is cached

在使用 lru_cache 之前,我的函数调用既低效又缓慢。有了缓存,重复调用几乎可以瞬间完成,节省了宝贵的计算时间。

对于数据处理中需要多次执行相同计算的函数,这个技巧尤其有用。它让我的代码变得更快、更高效。请尝试在你的项目中使用 lru_cache,看看性能提升的效果!

秘诀 7:生成器和 yield

发现生成器和 yield 关键字对我来说是一个转折点。生成器是一种特殊函数,通过一次生成一个元素的方式返回可迭代序列,节省内存并支持延迟计算。

示例

我曾经处理过无法同时放入内存的大型数据集。在我发现生成器之前,高效地迭代这些数据集是一项挑战:

def generate_squares(n):
    for i in range(n):
        yield i * i

# Use the generator
for square in generate_squares(5):
    print(square)

在使用生成器之前,我会创建大量列表,占用大量内存:

def generate_squares(n):
    result = []
    for i in range(n):
        result.append(i * i)
    return result

for square in generate_squares(5):
    print(square)

生成器确实是处理大型数据集的强大工具,它们可以有效地减少内存消耗并提高性能。通过逐步生成数据,而不是一次性读取整个数据集,生成器可以在处理大文件和数据流时节省大量资源。

使用yield语句可以将函数转变成生成器,这意味着它可以暂停和继续执行,使得代码更加灵活和高效。此外,生成器还可以与循环结合使用,用于处理大型数据集,或者实现惰性计算,以及其他各种应用场景。

秘诀 8:itertools 模块

在我很多项目中,都会经常用到itertools 模块。它提供了高效的数据遍历工具函数,如排列、组合和笛卡尔积等,极大提升了迭代处理的性能。

示例

我经常需要从一个项目列表中生成所有可能的配对或组合。在使用 itertools 之前,我的代码既笨重又低效。下面是 itertools 如何简化它的:

import itertools

# 生成两个项目的所有可能组合
items = ['A''B''C']
combinations = itertools.combinations(items, 2)

for combo in combinations:
    print(combo)

在使用 itertools 之前,生成组合需要嵌套循环,而且容易出错:

items = ['A''B''C']
combinations = []

for i in range(len(items)):
    for j in range(i + 1, len(items)):
        combinations.append((items[i], items[j]))

for combo in combinations:
    print(combo)

itertools 使我的代码更高效、更易读。它对涉及复杂迭代的任务特别有用,比如生成用于算法测试的排列组合或创建用于数据分析的笛卡尔积。将 itertools 纳入您的项目,性能和简洁性将得到显著提高!

秘诀 9:types.MappingProxyType映射代理类型

有次我遇到了防止字典意外修改的需求,types.MappingProxyType为我提供了绝佳解决方案。它能创建字典的只读映射视图,确保底层字典的内容永保不变。

示例

我正在做一个项目,其中的配置设置必须在整个执行过程中保持不变。下面是 MappingProxyType 的功能:

from types import MappingProxyType

# 原始字典
config = {'host''localhost''port':8080}

# 创建只读视图
read_only_config = MappingProxyType(config)

print(read_only_config['host']) # 输出:localhost

# 尝试修改只读字典
try:
    read_only_config['host'] = '127.0.0.1'
except TypeError as e:
    print(e)  # Output: 'mappingproxy' object does not support item assignment

在使用 MappingProxyType 之前,我一直担心字典会被更改:

config = {'host''localhost''port': 8080}

# 没有防止意外修改的保护措施
config['host'] = '127.0.0.1'

通过使用 types.MappingProxyType 我确保了配置设置的安全,避免了意外更改。在必须保护关键数据结构的情况下,这种技术尤其有用。试一试,就能增强代码的安全性和稳定性!

秘诀 10:pathlib 模块

pathlib模块则是现代化的文件路径操作利器。相较于os.path,它采用了面向对象的方式,操作更加易读,也降低了出错风险,成为文件路径处理的不二选择。

示例

我曾经使用 os.path 来处理文件操作,但我的代码往往杂乱无章,难以阅读。下面是 pathlib 如何改进它的:

from pathlib import Path

# 创建路径对象
path = Path('example_directory/example_file.txt')

# 检查路径是否存在
if path.exists():
    print(f"{path} exists")

# 从文件中读取文本
content = path.read_text()
print(content)

# 将文本写入文件
path.write_text('Hello, world!')

在使用 pathlib 之前,我的代码中充满了 os.path 函数:

import os

path = 'example_directory/example_file.txt'

# 检查路径是否存在
if os.path.exists(path):
    print(f"{path} exists")

# 从文件中读取文本
with open(path, 'r') as file:
    content = file.read()
    print(content)

# 将文本写入文件
with open(path, 'w') as file:
    file.write('Hello, world!')

使用 pathlib 使我的文件操作更简洁、更直观。它对于管理文件路径和简化文件处理任务尤其有用。试试 pathlib,看看它如何简化你的代码!


🏴‍☠️宝藏级🏴‍☠️ 原创公众号『数据STUDIO』内容超级硬核。公众号以Python为核心语言,垂直于数据科学领域,包括可戳👉 PythonMySQL数据分析 数据可视化机器学习与数据挖掘爬虫 等,从入门到进阶!

长按👇关注- 数据STUDIO -设为星标,干货速递

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/171731
 
184 次点击