玩命加载中 . . .

Python Tips and Tricks


Overview

分享一下在平时工作中所积累的技巧,供参考。

推导式

O(∩_∩)O哈哈~,开篇讲述一下推导式。

Python中的推导式(comprehensions)是一种简洁、高效地生成序列数据结构(如列表、字典、集合)的方法。

列表推导式(List comprehensions)

列表推导式是一个表达式,接一个 for 语句,然后有零到多个 for 或 if 语句。它的结果是一个列表,由 for 和 if 语句上下文中计算出来的表达式得来。例如:

squares = [x**2 for x in range(10)]

上述列表推导式生成了一个包含从0到9(包括9)的所有数字的平方的列表。

字典推导式(Dict comprehensions)

类似于列表推导式,字典推导式也可以用来创建字典。以下是创建一个数字到其平方映射的字典的例子:

squares_dict = {x: x**2 for x in range(5)}

这行代码生成了一个字典 {0: 0, 1: 1, 2: 4, 3: 9, 4: 16},它将0-4(包含4)的每个数字映射到它的平方。

集合推导式(Set comprehensions)

将列表推导式的中括号 [] 替换为大括号 {} 就可以创建集合。如下例:

squares_set = {x**2 for x in range(5)}

上述例子中生成了一个集合 {0, 1, 4, 9, 16},包含了0到4(包含4)的所有数字的平方。

条件推导式(Conditional comprehensions)

在推导式中使用 if 语句可以用来过滤条件。例如,下面这个例子生成了只包含偶数的平方的列表:

even_squares = [x**2 for x in range(10) if x % 2 == 0]

上述例子中生成了一个列表 [0, 4, 16, 36, 64],包含了0到9(包含9)的所有偶数的平方。

生成器推导式(Generator comprehensions)

生成器推导式是一种更高效的数据处理方式。它们与列表推导类似,但是使用圆括号 () 代替方括号 []。生成器推导式会返回一个生成器对象,可以通过 next() 函数或 for 循环来逐个获取元素,而不是一次性生成所有元素。因此,它们在处理大数据量时可以节省大量内存。

squares_gen = (x**2 for x in range(10))

上述例子中生成了一个生成器对象 squares_gen。你可以使用 next(squares_gen) 来逐个获取值,或者直接在 for 循环中使用它。

map()

说明:

这里简单介绍一下map,除了map之外,还有filter和reduce,未来有时间会整理一份这三个函数的使用方法与区别。

map() 是 Python 内置函数,用于将一个函数应用于一个输入列表(或其他可迭代对象)的所有元素。map() 函数的返回结果是一个 map 对象,是一个迭代器对象。

map()基本用法

map() 函数的基本语法如下:

map(function, iterable)
  • function:一个函数,它接收一个参数

  • iterable:一个或多个可迭代的对象

函数 function 将被应用到 iterable 的每一个元素。如果提供了额外的 iterable 参数,则 function 必须接收相同数量的参数,并且会被并行地应用于所有的 iterable 参数的元素。

例如,考虑以下场景,你有一个数字列表,你需要获取列表中所有数字的平方:

numbers = [1, 2, 3, 4, 5]
squared = map(lambda x: x ** 2, numbers)

在这个示例中,lambda x:x ** 2 是一个匿名函数,用于计算一个数的平方。map()函数将这个函数应用到列表numbers` 中的每一个元素。

要看到 map() 函数的返回结果,你可以将其转化为列表:

print(list(squared))  # 输出: [1, 4, 9, 16, 25]

注意,map() 返回的是一个可迭代的 map 对象,所以转化为列表后可以直接打印。

map()应用

根据条件在序列中筛选数据:

假设有一个数字列表 data, 过滤列表中的负数

data = [1, 2, 3, 4, -5]
  
# 使用列表推导式
result = [i for i in data if i >= 0]
  
# 使用 fliter 过滤函数
result = filter(lambda x: x >= 0, data)

再比如学生的数学分数以字典形式存储,筛选其中分数大于 80 分的同学

from random import randint
  
d = {x: randint(50, 100) for x in range(1, 21)}
r = {k: v for k, v in d.items() if v > 80}

zip()

Python内置函数zip()是一个生成器,用于将两个或更多个可迭代对象的元素配对生成新的可迭代对象,即生成一个元组的迭代器,其中第i个元组包含来自每个参数序列或可迭代对象的第i个元素。

当所输入可迭代对象中最短的一个被耗尽时,迭代器将停止迭代。

zip()的基础用法

numbers = [1, 2, 3]
letters = ['a', 'b', 'c']
zipped = zip(numbers, letters)

print(list(zipped))  # 输出:[(1, 'a'), (2, 'b'), (3, 'c')]

这段代码将列表numbers和letters中的元素配对,然后将配对的元组放入到新的列表中。

zip()用于不等长输入

如果输入的列表长度不相等,zip()会在最短的列表耗尽后停止:

numbers = [1, 2, 3]
letters = ['a', 'b']
zipped = zip(numbers, letters)

print(list(zipped))  # 输出:[(1, 'a'), (2, 'b')]

这里,由于letters列表只有两个元素,所以返回的结果只包含两个元组,numbers中的3被忽略了。

zip()用于大于两个的输入

zip()函数同样可以接受两个以上的输入序列:

numbers = [1, 2, 3]
letters = ['a', 'b', 'c']
floats = [4.0, 5.0, 6.0]
zipped = zip(numbers, letters, floats)

print(list(zipped))  # 输出:[(1, 'a', 4.0), (2, 'b', 5.0), (3, 'c', 6.0)]

在这个例子中,我们将三个列表中的元素配对,生成了一个包含三个元素的元组列表。每个元组都包含来自所有输入列表的对应元素。

使用zip()进行解压

zip()函数的一个常见用法是和*运算符(解包运算符)一起使用来解压序列。基本上,这意味着你可以使用zip()将配对的元组序列转换回两个独立的序列(列表、元组等):

zipped_list = [(1, 'a'), (2, 'b'), (3, 'c')]
numbers, letters = zip(*zipped_list)

print(numbers)  # 输出:(1, 2, 3)
print(letters)  # 输出:('a', 'b', 'c')

这个例子展示了如何将之前通过zip()函数打包的列表zipped_list解压回两个独立的元组。

在迭代中同时使用zip()

zip()函数在同时迭代多个序列时特别有用。通过zip(),你可以更为优雅地执行操作,而不是使用索引。例如,比较两个列表中相同位置上元素的大小:

list1 = [1, 2, 3, 4]
list2 = [4, 2, 2, 5]

for x, y in zip(list1, list2):
    if x > y:
        print(f'{x} is greater than {y}')
    elif x < y:
        print(f'{x} is less than {y}')
    else:
        print(f'{x} is equal to {y}')

这样,你可以同时迭代list1和list2中的元素,并进行比较。

对字典的键值对进行翻转

zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。

from random import randint, sample
  
s1 = {x: randint(1, 4) for x in sample("abfcdrg", randint(1, 5))}
d = {k: v for k, v in zip(s1.values(), s1.keys())}

小结

zip()是Python中一个非常强大且有用的内置函数,它使得在处理多个序列时,代码更加清晰,易读,并且Pythonic。无论是进行并行迭代,还是需要将数据形式互相转换时,zip()都可以被有效地使用。

pprint

Python内置的pprint模块提供了一个“漂亮打印(pretty printer)”的功能,用于生成数据结构的格式化表示,使其更易于阅读。这对于调试,或者当你需要以易于理解的格式输出复杂的数据结构(如深层嵌套的字典或列表)时非常有用。

基本用法

要使用pprint模块的基本功能,你需要先导入该模块,然后使用pprint()函数。这里有一个简单的例子展示如何使用它打印一个复杂的数据结构:

import pprint

data = [{
    'name': 'John',
    'age': 30,
    'city': 'New York'
}, {
    'name': 'Jane',
    'age': 25,
    'city': 'Paris'
}]

pprint.pprint(data)

上述代码输出效果如下:

>>> pprint.pprint(data)
[{'age': 30, 'city': 'New York', 'name': 'John'},
 {'age': 25, 'city': 'Paris', 'name': 'Jane'}]
>>> 

小结

pprint.pprint()函数将自动为你格式化输出,使其更加易读。与标准的print()函数相比,pprint()对于复杂数据结构的输出会自动换行并适当缩进。

定制化

pprint模块提供了多种方式来定制输出格式。PrettyPrinter类提供了更多的定制选项,包括控制输出宽度,深度,以及每行元素的数量。你可以创建一个PrettyPrinter实例,并用它来打印数据:

pp = pprint.PrettyPrinter(indent=4, width=41, depth=2)
pp.pprint(data)

在这个例子中,我们指定了缩进为4个空格,最大宽度为41字符,以及最大深度为2。当数据结构的深度超过depth参数时,pprint会用…来标示更深层的内容。

排序字典键

默认情况下,从Python 3.8开始,pprint会根据字典中键的插入顺序来打印字典。在更早的版本中(或如果你需要不同的行为),你可以通过sort_dicts=False参数来控制是否需要对字典键进行排序。例如:

pprint.pprint(data, sort_dicts=True)

这个例子将确保字典中的键在打印时按照升序排序。

pprint() 和 pformat()

除了pprint()函数,pprint模块还提供了一个pformat()函数,它返回一个格式化后的字符串而不是直接打印。这在你需要将格式化后的字符串用于日志记录、存储或通过网络发送时非常有用:

formatted_str = pprint.pformat(data)
print(formatted_str)

这样,你就能获取到格式化后的字符串并且可以自由地使用它。

小结

总的来说,pprint模块是一个非常有用的工具,特别是在处理复杂的数据结构时。它通过提供清晰的格式化输出,增强了Python的可读性和调试能力。通过使用pprint.PrettyPrinter类和相关的函数,你可以精确地控制输出的格式,使其满足你的具体需求。

sh

Python 的 sh 模块是一个第三方库,它提供了一个简单易用的接口来执行 shell 命令。它允许你从 Python 脚本中运行命令行指令,并捕获它们的输出。

安装

首先,你需要安装 sh 模块。你可以使用 pip 来安装它:

pip install sh

使用

sh 模块提供了几个函数来执行命令,其中最常用的是 sh() 函数。以下是一些基本的用法示例:

执行命令并捕获输出

import sh

result = sh.sh('echo "Hello, World!"')
print(result)

这将输出:

Hello, World!

获取命令的输出

sh.sh() 函数返回一个 sh.Result 对象,其中包含了命令的输出、错误、退出状态等信息。

output = sh.sh('ls')
print(output.stdout)  # 命令的标准输出
print(output.stderr)  # 命令的标准错误输出
print(output.exit_code)  # 命令的退出状态码

执行多个命令

你可以使用分号 ; 或者 && 来在一行中执行多个命令。

output = sh.sh('echo "First"; echo "Second"')
print(output.stdout)

使用管道

sh 模块支持使用管道 | 来将一个命令的输出传递给另一个命令。

output = sh.sh('ls | grep "test"')
print(output.stdout)

捕获错误

如果你想要捕获命令执行中的错误,可以使用 sh.ErrorReturnCode 异常。

try:
    output = sh.sh('cat non_existent_file.txt')
except sh.ErrorReturnCode as e:
    print("An error occurred:", e)

注意事项:

  • 使用 sh 模块时,应该小心处理用户输入,以避免潜在的安全风险,如 shell 注入攻击。

  • sh 模块主要用于简单的命令行操作。对于更复杂的 shell 脚本任务,你可能需要使用 Python 的 subprocess 模块,它提供了更多的灵活性和控制。

list转字符串

在Python中,如果你想将列表中的所有元素连接成一个字符串,可以使用join()方法,它是str类型的一个方法。

join()方法接受一个可迭代参数(如列表),并将其连接成一个字符串。它是通过将每个元素转化成字符串,然后使用调用join()方法的字符串作为分隔符将它们连接起来。

考虑以下例子:

list1 = ['Hello', 'world', '!']
str1 = ' '.join(list1)
print(str1)  # 输出:'Hello world !'

在这个例子中,我们使用空格(’ ')作为分隔符,将list1中的所有元素连接成了一个字符串。

注意,join()方法只能用于字符串的列表。如果列表中包含非字符串元素,则需要在使用join()前将它们转化为字符串。例如:

list2 = [1, 2, 3, 4, 5]
str2 = ''.join(str(e) for e in list2)
print(str2) # 输出:'12345'

上述代码通过列表推导式将list2中的所有元素转化为字符串,然后用空字符串(‘’)作为分隔符将它们连接起来。

频率统计

Python的collections模块提供了一系列扩展的容器类型,它提供了比通常的内置类型(如列表、字典和元组)更丰富的功能。其中一个非常有用的类是Counter,它主要用于对可哈希对象进行计数。

Counter类

Counter是一个字典子类,用于计算可哈希对象的频率。它是自动的哈希表,用于计数对象。元素作为键存储在Counter对象中,它们的计数作为值。

基本用法

from collections import Counter

# 创建一个Counter对象
c = Counter(['apple', 'orange', 'banana', 'apple', 'orange', 'apple'])
print(c)
# 输出:Counter({'apple': 3, 'orange': 2, 'banana': 1})

# 也可以直接用字符串初始化
c = Counter("abracadabra")
print(c)
# 输出:Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})

访问计数

# 获取任何元素的计数
print(c['a'])  # 输出:5

# 访问不存在的键,不会报错而是返回0
print(c['z'])  # 输出:0

更新计数

你可以更新Counter对象中的元素计数。使用update()方法可以增加计数,而减少计数则可以通过从Counter对象中减去另一个Counter对象来完成。

c.update(['a', 'b'])
print(c)
# 输出:Counter({'a': 6, 'b': 3, 'r': 2, 'c': 1, 'd': 1})

c.subtract(['a', 'b'])
print(c)
# 输出:Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})

方法和操作

Counter对象支持类似于字典的方法,并提供了一些有用的额外功能,如elements()、most_common()等:

# 获取计数最多的n个元素
print(c.most_common(2))
# 输出:[('a', 5), ('b', 2)]

# 获取所有元素的迭代器
print(list(c.elements()))
# 输出:['a', 'a', 'a', 'a', 'a', 'b', 'b', 'r', 'r', 'c', 'd']

其他collections类

除了Counter之外,collections模块还提供了许多其他有用的类:

  • namedtuple():为元组中的每个位置命名,提供更具可读性的元组子类。

  • OrderedDict:字典的子类,保留了他们被添加的顺序。

  • defaultdict:字典的子类,为字典查询提供了一个默认值。

  • deque:类似列表的容器,支持从头部和尾部高效地添加和删除元素。

Counter示例

对某英文文章单词进行统计,找到出现次数最高的单词以及出现的次数

import re
from collections import Counter
  
# 统计某个文章中英文单词的词频
with open("test.txt", "r", encoding="utf-8") as f:
  d = f.read()
  
# 所有的单词列表
total = re.split("\W+", d)
result = Counter(total)
print(result.most_common(10))

繁体字转简体字,简体字转繁体字

在Python中,繁体字与简体字之间的转换可以通过第三方库完成。一个常用的库是OpenCC,它能够在不同中文字符集之间进行转换,包括繁体字、简体字等。

安装OpenCC

首先,你需要安装opencc-python-reimplemented库,这是OpenCC的Python接口。可以通过pip命令安装:

pip install opencc-python-reimplemented

简体转繁体

使用OpenCC进行简体字到繁体字的转换如下:

from opencc import OpenCC
cc = OpenCC('s2t')  # 定义转换方向为简体到繁体
converted = cc.convert('简体中文转换成繁体中文')
print(converted)

繁体转简体

同样,你也可以将繁体字转换为简体字:

cc = OpenCC('t2s')  # 定义转换方向为繁体到简体
converted = cc.convert('繁體中文轉換成簡體中文')
print(converted)

转换方向

OpenCC支持以下转换方向:

  • s2t : 简体中文到繁体中文

  • t2s : 繁体中文到简体中文

  • s2tw : 简体中文到台湾正体

  • tw2s : 台湾正体到简体中文

等等,更多转换方向可以在OpenCC的文档中找到。

除了OpenCC,还有哪些用于中文字符集转换的工具?

除了OpenCC,还有一些其他工具和库可用于中文字符集的转换,包括简体和繁体中文之间的转换。下面列出了一些常用的选项:

1. HanLP

HanLP不仅提供了中文字符集的转换功能,还是一个全方位的中文自然语言处理库,支持词性标注、命名实体识别等多种功能。

HanLP的简繁转换需要使用到特定的API,它包含更广泛的自然语言处理功能。

2. hanziconv

hanziconv 是一个轻量级的Python库,提供了简单易用的繁简转换功能。

pip install hanziconv
from hanziconv import HanziConv

print(HanziConv.toSimplified('漢字轉換器'))  # 繁体到简体
print(HanziConv.toTraditional('汉字转换器'))  # 简体到繁体

3. cjklib

cjklib 提供了中日韩文字符处理的工具,包括读音信息、字符数据以及中文字符集的转换。

pip install cjklib

cjklib 的使用更偏向于学术研究和详细的字符信息处理,对于一般的繁简转换来说,可能功能略显复杂。

4. langconv & zhconv (Python 2)

对于Python2的用户,langconv(简繁转换)和zhconv(更适合网络爬虫)是历史上曾被较广泛使用的库,这两个库基于MediaWiki的繁简转换表实现,但它们在Python3上可能需要做一些修改才能使用。

# langconv 示例(对于Python 3可能需要进行修改才能运行)
from langconv import *

# 简体转繁体
traditional_sentence = Converter('zh-hant').convert(simplified_sentence)
print(traditional_sentence)

# 繁体转简体
simplified_sentence = Converter('zh-hans').convert(traditional_sentence)
print(simplified_sentence)

小结

每个库和工具都有其优势和特点,选择哪一个取决于你的具体需求、Python版本以及你希望集成的其他功能。对于简单的繁简转换来说,hanziconv 因其简洁易用而受到推荐;而如果你需要更全面的自然语言处理功能,则可能会倾向于选择HanLP。

文件查找

在Python中,有多种方法可以查找文件。这里需要的主要库是os和glob。

使用os.walk()

os.walk()是一种简单的遍历目录树的方式,对于查找文件特别有用。以下是如何使用os.walk()查找特定文件的方法:

import os

def find_file(filename, search_path):
   for root, dir, files in os.walk(search_path):
      if filename in files:
         return os.path.join(root, filename)
            
result = find_file('my_file.txt', '/path/to/directory')

在这个例子中,os.walk()会遍历/path/to/directory中的所有子目录并检查每个目录中的文件。当找到与filename匹配的文件时,会返回该文件的完整路径。

使用glob.glob()

glob模块是另一种查找文件的方式,它支持Unix风格的路径名模式。这对于需要匹配特定模式的文件名(如查找所有.txt文件)非常有用:

import glob

def find_files(pattern, path):
    return glob.glob(f'{path}/**/{pattern}', recursive=True)

results = find_files('*.txt', '/path/to/directory')

在这个示例中,glob.glob() 用于查找 /path/to/directory 中的所有 .txt 文件。星号 * 是一个通配符,表示任何字符(除了目录分隔符)。 {pattern} 是文件名模式,这里我们搜索所有的 .txt 文件。

recursive=True 参数让 glob 在所有子目录中查找匹配的文件,就像 os.walk() 那样。

注意:

glob.glob() 返回的是所有匹配的文件路径列表,而 os.walk() 则是在找到第一个匹配的文件后就返回。根据你的需求,你可能需要只找到第一个匹配的文件,或者返回所有匹配的文件列表。

使用 os.listdir() 和 fnmatch()

os.listdir() 可以列出一个目录中的所有文件和子目录,并且可以与 fnmatch 模块结合,用来对文件名进行模式匹配。

import os
import fnmatch

def find_file(pattern, path):
    result = []
    for filename in os.listdir(path):
        if fnmatch.fnmatch(filename, pattern):
            result.append(os.path.join(path, filename))
    return result

results = find_file('*.txt', '/path/to/directory')

这段代码会查找指定目录 /path/to/directory 中所有匹配 *.txt 模式的文件,并将它们的完整路径添加到 result 列表中。

fnmatch.fnmatch() 函数检查文件名是否符合Unix filename pattern匹配。

注意:

  • 当目录结构非常大时,进行文件搜索操作可能会比较耗时。

  • 如果你正在处理非常特定的需求(如文件属性或创建日期),可能需要编写更复杂的文件搜索逻辑。

  • Python的 Pathlib 模块在 Python 3.4 中引入,提供了面向对象的文件系统路径处理方法。以下是使用 Pathlib 查找文件的简化示例:

from pathlib import Path

def find_files(pattern, path):
    return Path(path).rglob(pattern)

results = find_files('*.txt', '/path/to/directory')
for result in results:
    print(result)  # prints the full path to each matching file

Path.rglob() 方法用于递归搜索符合给定模式的所有文件,这里 rglob 类似于带有 recursive=True 参数的 glob.glob()。

选择最佳方法取决于你的具体需求、可能的性能考虑以及你对代码的个人偏好。

时间转换

直接上之前自动化测试框架中的封装好的函数:

import time
import datetime


def sec2str(secs):
    """
    Change the seconds to a time format :%Y-%m-%d %H:%M:%S
    :param secs, int, a seconds time, such as 1535705378.02
    """
    if int(secs) < 0:         
        return ""

    return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.localtime(secs))


def get_date_time(**kwargs):
    """  Return a data time, format is '%Y-%m-%d %H:%M:%S'  """
    date_time = (datetime.datetime.now() + datetime.timedelta(**kwargs)).strftime('%Y-%m-%d %H:%M:%S')
    logging.debug("--  Current date time is : (%s)", date_time)
    return date_time


def change_timestamp_to_time(timestamp):
    """
    Change the timestamp to time, such as 1479264792 to 2016-11-16 10:53:12
    :param timestamp, string, a timestamp
    """ 
    time_struct = time.localtime(timestamp)
    return time.strftime('%Y-%m-%d %H:%M:%S', time_struct)

            
def change_date_time_to_timestamp(date_time):
    """         
    Change time to timestamp 
    :param date_time, string, a time, such as 2016-11-16 10:53:12
    """
    time_arry = time.strptime(date_time, "%Y-%m-%d %H:%M:%S")
    timestamp = time.mktime(time_arry)
    return timestamp

随机生成

随机验证码的生成

在Python中,生成随机验证码涉及到两个主要步骤:生成随机字符,然后将这些字符连接成一个字符串。常用的方法是使用Python内置的random和string模块。

以下是一个简单的例子,生成一个包含大小写字母和数字的6位随机验证码:

import random
import string

# 验证码由数字和字母(大写和小写)组成
chars = string.ascii_letters + string.digits

# 随机生成六位验证码
code = ''.join(random.choice(chars) for _ in range(6))

print(code)  # 类似输出:'a3BZ9d'

这段代码的工作原理如下:

  • string.ascii_letters是string模块中的一个预定义字符串,包含所有ASCII码的大小写字母。

  • string.digits 是一个包含所有数字的字符串。

  • random.choice(chars) 会从 chars 字符串中随机挑选一个字符

如果你想生成一个包含特殊字符的随机验证码,可以通过在字符集中加入特殊字符来实现。Python的string模块中已经定义了一些常用字符集,例如字母和数字,而特殊字符则需要你根据需求自定义添加。

以下是一个示例,展示了如何生成一个包含大小写字母、数字和特定特殊字符的随机验证码:

import random
import string

# 定义验证码的组成部分:包括大小写字母、数字、特殊字符
chars = string.ascii_letters + string.digits + "!@#$%^&*()"

# 随机生成一个六位长度的验证码
code = ''.join(random.choice(chars) for _ in range(6))

print(code)  # 示例输出:'aB3!$@'

这里,通过string.ascii_letters和string.digits增加了字母和数字,加号(+)被用于字符串的连接,"!@#$%^&*()"是一个包含特殊字符的字符串。random.choice(chars)将从这个组合的字符串中随机选择字符,range(6)定义了验证码的长度为6个字符。

此外,如果你想生成包含更多或不同特殊字符的验证码,只需调整包含在chars字符串中的特殊字符即可。

注意:

在使用特殊字符时,要确保所选特殊字符与你的应用场景兼容。某些场合可能对可用的特殊字符有限制。

生成随机IP地址

def random_IP():
    random_list = random.sample(range(1,256)*4, 4)
    str_random_list= map(str, random_list)
    return '.'.join(str_random_list)

随机的生成指定长度的Ascii和数字

def rand_low_ascii(length=10):
    """
    随机的生成指定长度的Ascii和数字.
    len指定的是生成的字符串的长度.
    :param length, string, Randomly generated string length, default is 10
    """
    return ''.join([choice(ascii_lowercase) for i in xrange(length)])

随机生成指定长度的数字

def rand_alpha(length=9):
    """
    随机生成指定长度的数字
    :param length, string, The length of the randomly generated number, default is 9
    """
    return ''.join([choice(digits) for i in xrange(length)])

随机返回类的一个成员值

def random_member(ClassName):
    """
    抽取类中的成员,随机返回一个成员值
    注:一定要保证类有__doc__值
    :param ClassName, object, a class name
    """
    member = ClassName.__dict__
    if member.get('__module__') is not None:
        del member['__module__']
    if member.get('__doc__') is not None:
        del member['__doc__']
    membertuple = member.items()
    randomvalue = membertuple[random.randint(0, len(membertuple)-1)]

    return randomvalue[1]

去除列表中重复元素

在Python中,可以通过多种方式去除列表中的重复元素。以下是几种常见的方法:

方法1. 使用集合(set)

将列表转换成集合会自动移除重复元素,因为集合里的元素是唯一的。但是,这种方法会丢失原始列表的顺序。

my_list = [1, 2, 2, 3, 4, 4, 5]
my_set = set(my_list)
unique_list = list(my_set)
print(unique_list)  # 输出:[1, 2, 3, 4, 5]

方法2. 使用字典

字典的键也是唯一的。通过将列表元素作为字典的键,可以移除重复元素。这种方法同样会丢失原始列表的顺序,但在Python 3.7+中,字典是有序的,因此可以保持顺序。

my_list = [1, 2, 2, 3, 4, 4, 5]
unique_list = list(dict.fromkeys(my_list))
print(unique_list)  # 输出:[1, 2, 3, 4, 5]

方法3. 列表推导式

使用列表推导式检查元素是否已经在新列表中,从而保留元素的原始顺序。这种方法适用于较小的列表,对于大列表可能效率较低。

my_list = [1, 2, 2, 3, 4, 4, 5]
unique_list = []

[unique_list.append(x) for x in my_list if x not in unique_list]

print(unique_list)  # 输出:[1, 2, 3, 4, 5]

方法4. 使用collections.OrderedDict

从Python 3.7开始,字典是有序的。但在早期版本中,可以使用collections.OrderedDict来保持原始列表的顺序。

from collections import OrderedDict

my_list = [1, 2, 2, 3, 4, 4, 5]
unique_list = list(OrderedDict.fromkeys(my_list))
print(unique_list)  # 输出:[1, 2, 3, 4, 5]

方法5. 使用pandas库

如果你在使用pandas库,可以利用它移除重复元素并保持顺序。

import pandas as pd

my_list = [1, 2, 2, 3, 4, 4, 5]
unique_list = pd.Series(my_list).drop_duplicates().tolist()

print(unique_list)  # 输出:[1, 2, 3, 4, 5]

选择哪种方法取决于你的具体需求,包括是否需要保持列表的原始顺序、列表的大小以及是否已经在使用如pandas这样的第三方库。

根据字典中值的大小,对字典中的项进行排序

比如班级中学生的数学成绩以字典的形式存储,请按数学成绩从高到底进行排序

方法1: 利用 zip 将字典转化为元组,再用 sorted 进行排序

from random import randint
  
data = {x: randint(60, 100) for x in "xyzfafs"}
sorted(data)
data = sorted(zip(data.values(), data.keys()))

方法2: 利用 sorted 函数的 key 参数

from random import randint
  
data = {x: randint(60, 100) for x in "xyzfafs"}
data.items()
sorted(data.items(), key=lambda x: x[1])

在多个字典中找到公共键

实际场景:在足球联赛中,统计每轮比赛都有进球的球员

第一轮:{“C罗”: 1, “苏亚雷斯”:2, “托雷斯”: 1…}
第二轮:{“内马尔”: 1, “梅西”:2, “姆巴佩”: 3…}
第三轮:{“姆巴佩”: 2, “C罗”:2, “内马尔”: 1…}

# 定义每轮比赛的球员和进球数的字典
round1 = {"C罗": 1, "苏亚雷斯": 2, "托雷斯": 1}
round2 = {"内马尔": 1, "梅西": 2, "姆巴佩": 3}
round3 = {"姆巴佩": 2, "C罗": 2, "内马尔": 1}

# 将每轮比赛的字典存储在一个列表中
rounds = [round1, round2, round3]

# 获取所有轮次的键的集合
keys_sets = [set(rnd.keys()) for rnd in rounds]

# 使用集合的交集找出所有轮次中共有的键
common_keys = set.intersection(*keys_sets)

# 输出共有的键,即在多个轮次中都有进球的球员
print("公共的键(球员):", common_keys)

# 统计公共键在整个比赛轮次中的进球总数
total_goals = {key: 0 for key in common_keys}

for rnd in rounds:
    for player, goals in rnd.items():
        if player in common_keys:
            total_goals[player] += goals

# 输出每个球员的总进球数
print("球员的总进球数:")
for player, goals in total_goals.items():
    print(f"{player}: {goals}")

使用 enumerate 获取迭代器索引和值

在迭代时获取索引和对应的值,在迭代一些可迭代对象时(例如list,dict),可通过内置enumerate来获取迭代元素的索引值

for index, value in enumerate(names):
    print(index, value)

使用列表解析展平列表

将嵌套的列表展平为一维列表。

nested_list = [[1, 2, 3], [4, 5], [6, 7, 8]]
flattened_list = [num for sublist in nested_list for num in sublist]
print(flattened_list)

结果:

[1, 2, 3, 4, 5, 6, 7, 8]

还有一种方式可以连接两个列表

a = [1, 2, 3]  
b = [5, 6, 7]  
  
c = [*a, *b]  
print(c)

结果:

[1, 2, 3, 5, 6, 7]

重复

重复列表

>>> [1,2,3] * 4
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]

重复字符串

>>> 'dog eat dog;' * 3
'dog eat dog;dog eat dog;dog eat dog;'
>>> 

字典合并

>>> a= {"a":1}
>>> b= {"b":2}
>>> {**a, **b}
{'a': 1, 'b': 2}
>>>

字符串反转

>>> s = "This is a dog eat dog world!"
>>> s[::-1]
'!dlrow god tae god a si sihT'
>>> 

文章作者: Gavin Wang
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Gavin Wang !
  目录