小知识dd

对于一个函数或未知的方法不知道下面有哪些可调用的属性时,用dir(函数/方法)即可查看

1、给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。

输入:nums = [3,2,4], target = 6
输出:[1,2]
# class Solution_1(object):
#     def twoSum(self, nums, target):
#         return [[nums.index(i),nums.index(target-i)] for i in nums if (target-i) in nums and (target-i) != i]

class Solution_2(object):
    def twoSum(self, nums, target):
        result = []
        seen = set()
        for i, num in enumerate(nums):
            if target - num in seen:
                result.append([nums.index(target - num), i])
            seen.add(num)
        return result

print(Solution_2().twoSum([1, 2, 3, 4, 5], 6))

2、给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
class Solution(object):
    def addTwoNumbers(self, l1, l2):
        res = []
        result = 0
        for i in range(len(l1)):
            result += l1[i] * 10**(i)
        for i in range(len(l2)):
            result += l2[i] * 10**(i)
        for i in range(1,(len(str(result)))+1):
            res.append(str(result)[-i])
        return res
print(Solution().addTwoNumbers([9,9,9,9,9,9,9], [9,9,9,9]))

3、给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

eg:

知识点:前序遍历:根节点 -> 左子树 -> 右子树;中序遍历:左子树 -> 根节点 -> 右子树;后序遍历:左子树 -> 右子树 -> 根节点

前序遍历:1, 2, 4, 5, 3, 6, 7;中序遍历:4, 2, 5, 1, 6, 3, 7;后序遍历:4, 5, 2, 6, 7, 3, 1

思路很简单,所有遍历都可从根root开始,如前序遍历规则为根—左—右:先遍历根:1__2__3__(有子树有空格),再遍历左:245(无子树不用空格),合并后就是1245__3__,最后遍历右:367,合并就是1245367。

中序遍历规则为左—根—右:先遍历根:2__1__3__,再遍历左:425,合并后就是4251__3__,最后遍历右:637,合并就是4251637。

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def buildTree(preorder, inorder):
    if not preorder or not inorder:
        return None
    
    root_val = preorder[0]
    root = TreeNode(root_val)
    
    # 在中序遍历中找到根节点的索引
    root_index = inorder.index(root_val)
    
    # 递归构建左右子树
    root.left = buildTree(preorder[1:1+root_index], inorder[:root_index])
    root.right = buildTree(preorder[1+root_index:], inorder[root_index+1:])
    
    return root

# 打印树结构
def print_tree(node, level=0, label='root'):
    print(' ' * (level * 4) + label + ':', node.val)
    if node.left:
        print_tree(node.left, level + 1, 'left')
    if node.right:
        print_tree(node.right, level + 1, 'right')

print_tree(buildTree([1, 2, 4, 5, 3, 6, 7], [4, 2, 5, 1, 6, 3, 7]))

4、给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是'wke',长度为3.
class Solution(object):
    def lengthOfLongestSubstring(self, s):
        result = pd.DataFrame()
        for i in range(len(s)):
            res = []
            res.append(s[i])
            for j in range(i+1, len(s)):
                if s[j] not in res:
                    res.append(s[j])
                    num = len(res)
                else:
                    num = len(res)
                    resu = pd.DataFrame({'name':''.join(res), 'len':num},index=[0])
                    result = pd.concat([result,resu])
                    break

                resu = pd.DataFrame({'name':''.join(res), 'len':num},index=[0])
                result = pd.concat([result,resu])
        result.sort_values(by='len', ascending=False, inplace=True)
        return result.head(1)

Solution().lengthOfLongestSubstring('pwwkew') # hdhedwhi

5、给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。算法的时间复杂度应该为 O(log (m+n)) 。

输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2): # O(nlogn)
        nums1.extend(nums2) # nums1 + nums2
        nums1.sort(reverse=False)
        if len(nums1) % 2 == 0:
            return (nums1[len(nums1)//2 - 1] + nums1[len(nums1)//2]) / 2
        else:
            return nums1[len(nums1)//2]

    def findMedianSortedArrays_1(self, nums1, nums2): # O(log(min(m, n)))
        if len(nums1) > len(nums2):
            nums1, nums2 = nums2, nums1
        m, n = len(nums1), len(nums2)
        left, right = 0, m
        total_len = (m + n + 1) // 2
        while left < right:
            i = (left + right) // 2
            j = total_len - i
            if i < m and nums2[j-1] > nums1[i]:
                left = i + 1
            else:
                right = i
        i = left
        j = total_len - i
        nums1_left_max = float('-inf') if i == 0 else nums1[i-1]
        nums1_right_min = float('inf') if i == m else nums1[i]
        nums2_left_max = float('-inf') if j == 0 else nums2[j-1]
        nums2_right_min = float('inf') if j == n else nums2[j]
        if (m + n) % 2 == 0:
            return (max(nums1_left_max, nums2_left_max) + min(nums1_right_min, nums2_right_min)) / 2
        else:
            return max(nums1_left_max, nums2_left_max)
    

print(Solution().findMedianSortedArrays([1,4,6],[2,5,8,10]))

6、给定一个字符串 s,找到 s 中最长的回文子串(如果字符串的反序与原始字符串相同,则该字符串称为回文字符串)。

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

def longestPalindrome(s):
    n = len(s)
    dp = [[False] * n for _ in range(n)]
    start = 0
    max_len = 1

    # 初始化长度为1和2的回文子串
    for i in range(n):
        dp[i][i] = True
        if i < n - 1 and s[i] == s[i + 1]:
            dp[i][i + 1] = True
            start = i
            max_len = 2
# 动态规划遍历
    # 遍历子串长度大于2的情况
    for len_ in range(3, n + 1):
        for i in range(n - len_ + 1):
            j = i + len_ - 1
            if s[i] == s[j] and dp[i + 1][j - 1]:
                dp[i][j] = True
                start = i
                max_len = len_

    return s[start:start + max_len]
s = "bsabasda"
longestPalindrome(s)

Python中常用的数据类型包括整数、浮点数、字符串、列表、元组、字典等。

Python中的控制流语句包括if语句、for循环和while循环,用于实现条件判断和循环操作。

函数是一段封装好的代码块,可以重复调用。在Python中定义函数使用关键字def

RTSP(Real Time Streaming Protocol)是一种用于在IP网络上传输音频和视频数据的协议。在Python中,我们可以使用第三方库来实现RTSP视频流的处理和播放。

安装相应的依赖库。其中最常用的库是OpenCV和FFmpeg:

pip install opencv-python
pip install ffmpeg-python

播放RTSP视频流:

import cv2
"""要确定一个视频流是否为RTSP流,可以通过检查流的URL协议:RTSP流通常使用rtsp://作为URL的协议前缀。因此,只需检查流的URL是否以rtsp://开头即可判断是否为RTSP流。
如果想正常使用可以通过一下办法自己搭建一个测试地址:
1.打开 https://rtsp.stream/;
2.拉取到最后,点击Free下的"Get started"填写邮箱;
3.打开邮箱,打开指定的链接后,会给出2个免费的有效地址,每月有2G流量可免费使用。
可通过VLC播放器直接打开播放
"""
rtsp_url = "rtsp://rtspstream:7e536546fadf62359810a7c9a53ad6fe@zephyr.rtsp.stream/pattern"


cap = cv2.VideoCapture(rtsp_url)

while True:
    ret, frame = cap.read()

    if ret:
        cv2.imshow("RTSP Stream", frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):# 在代码框里面输入q退出播放
        break

cap.release()
cv2.destroyAllWindows()

测试结果:

验证字符串包含:

1、使用in关键字:

s1 = 'hello'
s2 = 'hello world'
s1 in s2
# result: True

2、使用find方法:str1.find(str2):在str2中是否找到字符串str1

s1 = 'hello'
s2 = 'hello world'
s1.find(s2)
# result: -1:找到

3、使用re模块:re.search(s1, s2):在s2中能否找到s1

import re
s1 = 'hello'
s2 = 'hello world'
re.search(s1, s2)
re.findall(s1, s2)

# <re.Match object; span=(0, 5), match='hello'>

4、正则匹配

正则表达式(Regular Expression)是一种用来描述字符串匹配规则的字符序列

  • . : 匹配除换行符以外的任意字符。
  • ^ : 匹配字符串的开头。
  • $ : 匹配字符串的结尾。
  • * : 匹配0个或多个前面的字符。
  • + : 匹配1个或多个前面的字符。
  • ? : 匹配0个或1个前面的字符。
  • {} : 匹配特定次数的前面的字符。
  • [] : 匹配括号内的任意一个字符。
  • | : 匹配多个条件中的任意一个。

(?<= )是正则表达式中的一个零宽度正后发断言(Lookbehind Assertion),也称为后顾前瞻条件。它用于指定匹配的文本必须出现在某个特定模式之后,但该模式本身不包含在最终的匹配结果中。

(?=):是正向前瞻断言,它指定一个位置,该位置后面的字符串必须符合括号内的模式,但这个匹配的内容不会被包含在最终匹配的结果中。

实际上  .*  能匹配无限长的字符。

import re

html = """
<a href="https://www.google.com">Google</a>
<a href="https://www.baidu.com">Baidu</a>
"""

pattern = re.compile(r'(?<=href=").*(?=")')
results = pattern.findall(html)

print("提取到的链接是:", results)

5、用count方法判断是否包含:如果包含出现次数就>0

s = "hello world"
if s.count('a') > 0:
    print(s.count('a'))
else:
    print("no a")

6、用index()方法来查找子串在字符串中的位置:

# 使用index()方法查找子串

str1 = "Hello, World!"
sub_str = "World"

# 查找子串在字符串中的位置
try:
    index = str1.index(sub_str)
    print(f"子串在字符串中的位置为: {index}")
except ValueError:
    print("子串不在字符串中")

7、用startswith()endswith()方法判断字符串起始和结尾

str1 = "Hello, World!"
prefix = "Hello"
suffix = "World"

# 判断字符串是否以特定子串起始或结尾
if str1.startswith(prefix):

if str1.endswith(suffix):

输出列表最后一个元素:

1、使用负索引:显示元素

st = [1,2,3]
st[-1]

2、使用pop函数:会显示弹出的最后一个元素并会在原列表中删除

my_list = [1, 2, 3, 4, 5]
my_list.pop()

3、切片:返回的是包含最后一个元素的列表

my_list = [1, 2, 3, 4, 5]
my_list[-1:]

4、使用列表长度:

my_list[len(my_list)-1]

检查文件路径是否存在:

import os

def create_directory(directory_path):
    # 检查文件夹路径是否存在
    if os.path.exists(directory_path):
        # 如果存在则先删除
        os.remove(directory_path)
    
    if not os.path.exists(directory_path):
        # 如果不存在则创建文件夹
        os.makedirs(directory_path)

directory_path = 'path/to/directory'
create_directory(directory_path)

取出文件名中间几位:

在文件处理过程中,需要从文件名中提取特定位置的字符或信息,以便对文件进行分类、重命名或其它操作。

import os

def get_middle_chars_from_filename(filename, start, end):
    base = os.path.basename(filename)  # 获取文件名部分
    middle_chars = base[start:end]     # 提取中间字符
    return middle_chars

filename = "example_file_20211225.txt"
result = get_middle_chars_from_filename(filename, 13, 19)
print(result)

读取指定行的数据:

1、readline方法:可以用来逐行读取文件中的数据:

# 打开文件
with open('data.txt', 'r') as file:
    # 读取文件的第三行数据
    for i in range(3):
        line = file.readline()

    print(line)

2、readlines方法:可以一次性读取所有行的数据,并返回一个包含所有行的列表。从这个列表中找到需要的特定行:

# 打开文件
with open('data.txt', 'r') as file:
    # 读取所有行数据
    lines = file.readlines()

# 找到第五行数据
print(lines[4])

3、enumerate方法:遍历文件的每一行,并找到需要的特定行:

# 打开文件
with open('data.txt', 'r') as file:
    # 遍历文件的每一行
    for idx, line in enumerate(file):
        # 找到第六行数据
        if idx == 5:
            print(line)
            break

设置服务器代理:

使用requests库、urllib库、http.client库设置代理

计算两个日期之间的天数:

import datetime
print(datetime.date(2022, 1, 1)) # class 'datetime.date' : 2022-01-01
print(datetime.datetime.strptime('2022-01-01', '%Y-%m-%d')) # class 'datetime.datetime : 2022-01-01 00:00:00
print(datetime.date(2022, 1, 1).strftime('%Y-%m-%d')) # class 'str' : 2022-01-01
(datetime.date(2022, 12, 1) - datetime.date(2022, 1, 1)).days # 334
(datetime.datetime.strptime('2022-12-01', '%Y-%m-%d') - datetime.datetime.strptime('2022-01-01', '%Y-%m-%d')).days # 334

考虑闰年的影响。闰年是指可以被4整除但不能被100整除,或者可以被400整除的年份。在Python中,可以使用calendar模块中的isleap()函数来判断一个年份是否是闰年。

# 导入datetime和calendar模块
import datetime; import calendar
# 定义两个日期
date1 = datetime.date(2020, 2, 28); date2 = datetime.date(2021, 2, 28)
# 计算两个日期之间的天数
delta = date2 - date1 # 366
# 考虑闰年的影响
leap_days = sum(calendar.isleap(date1.year + x) for x in range(1,(date2.year - date1.year))) # 0
days = delta.days + leap_days # 366
print(days)

获取昨天的日期(或上一工作日的日期):

1、用datetime中的timedelta模块

import datetime
yesterday = datetime.date.today() - datetime.timedelta(days=1)
while True:
    yesterday = yesterday - datetime.timedelta(days=1)
    if yesterday.weekday() < 5:
        break
print(yesterday)

datetime.date(2018, 1, 1) - datetime.timedelta(days=1)

2、用arrow模块

import arrow
arrow.now().shift(days=-1).format('YYYY-MM-DD')

3、判断是否是节假日还是工作日,用holidays模块:

import holidays
# 创建中国节假日对象
china_holidays = holidays.China()
# 判断日期是否为节假日
date = '2024-04-04'
if date in china_holidays:
    print(f'{date} 是节假日')
else:
    print(f'{date} 不是节假日')

4、用workalendar模块:

from workalendar.asia import China

# 创建中国节假日对象
cal = China()

# 判断日期是否为调休
date = datetime.date(2023,2,9)
if cal.is_working_day(date):
    print(f'{date} 是调休日')
else:
    print(f'{date} 不是调休日')

时区转换:

import pytz
from datetime import datetime

utc_now = datetime.utcnow() # 获取当前的UTC时间
utc = pytz.utc
tokyo = pytz.timezone('Asia/Tokyo') # 转换成其他时区

tokyo_now = utc_now.replace(tzinfo=utc).astimezone(tokyo) # 用replace()方法将UTC时间转换成UTC时区时间,并使用astimezone()方法将其转换成东京时区时间
print(tokyo_now)

自动识别不同格式的日期:

用dateutil库中的parser处理:

from dateutil import parser

dates = ["2021-09-10", "10/09/2021", "2021年09月10日"]

for date_str in dates:
    date = parser.parse(date_str, fuzzy=True)
    print(date)


"""
2021-09-10 00:00:00
2021-10-09 00:00:00
2021-09-10 00:00:00
"""

获取当前日期:

import datetime
datetime.datetime.now().date() # 年-月-日
datetime.datetime(2020, 10, 15).date() # 指定日期的年-月-日


current_date = datetime.datetime.now()
year = current_date.year
month = current_date.month
day = current_date.day

datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") # 带时分秒

解码utf-8:

utf-8是一种最常用的字符编码方式,用来表示Unicode字符。在处理文本数据时,经常需要对utf-8进行解码操作:

# utf-8编码的字节数据
utf8_bytes = b'\xe4\xbd\xa0\xe5\xa5\xbd'

# 解码成字符串
utf8_str = utf8_bytes.decode('utf-8')

print(utf8_str)

数组(list)中的元素赋值:

1、索引赋值  2、切片赋值  3、循环赋值

arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
arr[1] = 'a'
arr[-1:] = [11]
for i in range(3,5):
    arr[i] += 10
print(arr)
# [1, 'a', 3, 14, 15, 6, 7, 8, 9, 11]

生成等差数列:

1、使用range函数  2、使用numpy库  3、用列表推导式

list(range(1, 11, 2)) # list
np.arange(1, 11, 2) # class 'numpy.ndarray'
[i for i in range(1, 11, 2)]

数据结构—字典操作:

字典是一种无序、可变、元素以键值对形式存储的数据结构

dict(**kwargs) # 传入关键字参数(可选)
my_dict = dict(name='Alice', age=30, city='New York')

dict(mapping, **kwargs) # 传入映射对象(字典)
mapping = {'name': 'Alice', 'age': 30, 'city': 'New York'}

dict(iterable, **kwargs) # 传入可迭代对象
iterable = [('name', 'Alice'), ('age', 30), ('city', 'New York')]
empty_dict = {} # empty_dict2 = dict()
# 添加元素
my_dict['name'] = 'Alice'
my_dict['age'] = 25

# 删除元素
del my_dict['name'] # del删除指定键的元素
age = my_dict.pop('age') # pop删除并返回指定键的值,键值都会删除
my_dict['age'] = 26 # 直接赋值修改
my_dict.clear()  # 清空字典
del my_dict  # 删除字典



# 访问元素
age = my_dict['age'] # 键不存在,会抛出KeyError
gender = my_dict.get('gender', 'Unknown') # 用get()方法进行安全访问

dict写入csv文件:

import csv

# 定义字典数据
data = [{"name": "Alice", "age": 25, "city": "New York"},
    {"name": "Bob", "age": 30, "city": "Los Angeles"},
    {"name": "Charlie", "age": 35, "city": "Chicago"}]

# 指定CSV文件路径
csv_file = "data.csv"

# 定义CSV文件的表头
fields = ["name", "age", "city"]

# 写入数据到CSV文件
with open(csv_file, mode='w', newline='') as file:
    writer = csv.DictWriter(file, fieldnames=fields)

    # 写入表头
    writer.writeheader() # 根据之前创建的Writer对象的设置,生成对应格式的表头并写入CSV文件中

    # 写入数据
    for row in data:
        writer.writerow(row)

当路径中包含空格时,可以使用双引号或原始字符串来表示路径:

file_path = r'C:/Program Files/file.txt'  # 使用原始字符串

解压rar文件:

可以用rarfile库来解压RAR文件:

import rarfile

def unrar_file(rar_file_path, extract_dir):
    rf = rarfile.RarFile(rar_file_path)
    rf.extractall(extract_dir)
    rf.close()

rar_file_path = "example.rar"
extract_dir_path = "output"
unrar_file(rar_file_path, extract_dir_path)

去除字符串末尾字符:

1、strip()方法:去除字符串前后的指定字符,默认情况下会去除空格、制表符和换行符。通过传入参数指定需要去除的字符,可以实现去除字符串末尾字符的功能。

str = "Hello World    "
new_str = str.strip()
print(new_str) # Hello World

2、rstrip()方法:只能去除字符串末尾的字符(区别不大)

3、切片:

new_str = str[:-4]

原子自增:

原子操作是一种能够确保一段代码在多线程或多进程环境下不会被打断的操作,ValueLock是两个常用的类:

multiprocessing中的Value类允许在多进程之间共享内存,并提供了一些原子操作方法,例如value.increment()

from multiprocessing import Process, Value

def increment_value(val): # 共享整型变量
    for _ in range(1000):
        val.value += 1

if __name__ == '__main__':
    val = Value('i', 0) # 创建一个整型的共享变量val,初始值为0。
    processes = [Process(target=increment_value, args=(val,)) for _ in range(4)] # 创建一个包含4个进程的列表processes

    for p in processes: # 循环依次启动4个进程
        p.start()

    for p in processes: # 循环等待所有进程执行完毕
        p.join()

    print("Final value:", val.value)

Lock来保护对共享资源的访问。通过with lock:语句,我们确保每次只有一个进程可以访问Value对象,并执行自增操作。这样就可以避免数据竞争带来的问题。

from multiprocessing import Process, Value, Lock

def increment_value(val, lock):
    for _ in range(1000):
        with lock:
            val.value += 1

if __name__ == '__main__':
    val = Value('i', 0)
    lock = Lock()

    processes = [Process(target=increment_value, args=(val, lock)) for _ in range(4)]

    for p in processes:
        p.start()

    for p in processes:
        p.join()

    print("Final value:", val.value)

列表初始化:

a = [] #直接赋值
[i for i in range(1, 4)] # 用列表解析式
list()方法 # list()方法
[0] * 3 # 用*操作符
list1 = [1, 2, 3]; list2 = [4, 5, 6]; my_list = list1 + list2 # 用+操作符
list1.extend(list2) # 用extend()方法
list(x for x in range(1, 4)) # 用生成器
list1.copy() # 用copy()方法
copy.deepcopy(list1) # 用deepcopy()方法
  1. 列表和元组在Python中是两种不同的数据结构,具有不同的特性,转换时需要注意可能存在的数据丢失或格式不一致的情况。
  2. 列表是可变的数据结构,元组是不可变的数据结构,转换时需确保数据安全性。
  3. 转换过程中不会改变原列表或元组的内容,只是将其复制一份到新的数据结构中,原数据结构将保持不变

元组和列表互转:

tuple(my_list) # my_list = [1, 2, 3, 4, 5]
list(my_tuple) # my_tuple = (1, 2, 3, 4, 5)

print(sys.getsizeof(my_list)) # 获取my_list占用的字节数
  • 整数类型:int(4字节)、long(8字节)、short(2字节)、byte(1字节)
  • 浮点数类型:float(4字节)、double(8字节)
  • 字符类型:char(2字节)
  • 布尔类型:boolean(1字节)

分割数据:

1、手动分割数据:

# 手动分割数据
train_data = data.iloc[:800, :]
test_data = data.iloc[800:, :]

2、用train_test_split函数:scikit-learn库中的train_test_split函数可以方便地将数据集分割成训练集和测试集:

from sklearn.model_selection import train_test_split
import pandas as pd

data = pd.read_csv('data.csv')

# 使用train_test_split函数分割数据  # 随机种子。可以是一个整数,用于确定划分数据集时的随机性。设置相同的随机种子可以保证每次划分的结果一致。如果不指定random_state,则每次划分的结果都会不同。
train_data, test_data = train_test_split(data, test_size=0.2, random_state=42)

3、用numpy的random.permutation方法:可以随机打乱数据集,再根据指定比例分割成训练集和测试集:

# 随机打乱数据集
data_shuffled = data.reindex(np.random.permutation(data.index))

# 分割数据
train_data = data_shuffled.iloc[:800, :]
test_data = data_shuffled.iloc[800:, :]

元组转字典:

元组用于存储不可变的数据集合,而字典用于存储键值对

1、dict()函数

tuples = [('a', 1), ('b', 2), ('c', 3)] # 定义一个包含2个元组的列表
result = dict(tuples) # 使用dict()函数将元组转换为字典

2、列表推导式

result = {key: value for key, value in tuples} # 使用字典推导式将元组转换为字典

集合是一种无序且不重复的数据结构。集合的特点是元素之间没有顺序关系,且集合中的元素不会重复。

用pop弹出集合元素时,集合是无序的,因此弹出的第一个元素可能是任意一个元素;弹出元素之后,原集合中将会删除这个元素。my_set.pop()

Python中嵌入C语言:

创建一个扩展模块:首先需要编写一个C语言源文件,其中包含我们需要实现的功能。然后通过Python的Distutils库将其编译为扩展模块,生成对应的共享库文件。

在Python代码中使用扩展模块:在Python代码中导入刚刚生成的扩展模块,并调用其中定义的函数来执行对应的操作。

// example.c

#include <Python.h>

// C语言函数实现
static PyObject* add(PyObject* self, PyObject* args) {
    int a, b;

    // 解析Python参数
    if (!PyArg_ParseTuple(args, "ii", &a, &b)) {
        return NULL;
    }

    // 执行计算并返回结果
    return Py_BuildValue("i", a + b);
}

// 方法列表
static PyMethodDef methods[] = {
    {"add", add, METH_VARARGS, "Add two integers"},
    {NULL, NULL, 0, NULL}
};

// 模块初始化函数
static struct PyModuleDef module = {
    PyModuleDef_HEAD_INIT,
    "example",
    NULL,
    -1,
    methods
};

PyMODINIT_FUNC PyInit_example(void) {
    return PyModule_Create(&module);
}
# main.py

import example

# 调用C语言函数
result = example.add(1, 2)
print(result)

子串的应用:

子串通常是原字符串的一个部分,也可以为空串,有很多应用场景:

str = "Hello, World!"
sub_str = "World"
if sub_str in str: # 匹配
    print("The substring is found.")

sub_str1 = str[:5]; sub_str2 = str[7:] # 切割
print(sub_str1 + sub_str2) # 连接

index = str.find(sub_str) # 查找
if index != -1:
    print("The substring is found at index", index)

new_sub_str = "Python"
new_str = str.replace(sub_str, new_sub_str) # 替换

相等比较(==) 和对象比较( is) 区别:

==被称为相等比较操作符,用于判断两个对象的值是否相等。当使用==比较两个对象时,Python会比较它们的值,如果它们的值相等,则返回True,否则返回False

is操作符用于比较两个对象是否是同一个对象,也就是它们的内存地址是否相等。如果两个对象的内存地址相等,则is会返回True,否则返回False

x = 10
y = 10
if x == y:

a = [1, 2, 3]
b = a
if a is b:

不同点:

==用于比较两个对象的值,而is用于比较两个对象的内存地址.。

==会调用对象的__eq__方法进行比较,而is直接比较对象的内存地址。

在比较基本数据类型(如整数、字符串)时,==和is的行为是相同的。但在比较复杂数据类型(如列表、字典)时,它们的行为可能不同。

何时使用==和is:

当需要比较两个对象的值时,应该使用==操作符。

当需要比较两个对象是否是同一个对象时,应该使用is操作符。

在比较字符串、整数等基本数据类型时,通常可以使用==操作符。但在比较列表、字典等复杂数据类型时,最好使用is操作符

搭建简单的HTTP服务器:

1、SimpleHTTPServer模块提供了一个简单的HTTP服务器,可以用于快速搭建一个静态文件服务器:

# 导入SimpleHTTPServer模块
import SimpleHTTPServer
import SocketServer

# 设置监听端口为8888
PORT = 8888

# 创建一个简单的HTTP服务器
Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)

# 启动服务器
print "Server started at port", PORT
httpd.serve_forever()

保存为server.py,在命令行中执行python server.py即可启动一个HTTP服务器,然后在浏览器中访问http://localhost:8888即可看到服务器的默认页面。

但目前python3.X没有该模块了,因此只需要在命令行中输入:

python -m http.server 8000

就可以启动一个静态服务器了。

SimpleHTTPServer模块默认会将当前目录作为根目录,我们可以通过http://localhost:8000来访问当前目录下的文件。

自定义根目录:如果想要使用自定义的根目录,可以使用BaseHTTPServer模块中的BaseHTTPRequestHandler类来重写do_GET方法,如下所示:

import SimpleHTTPServer
import SocketServer

PORT = 8888

class CustomHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type','text/html')
        self.end_headers()
        self.wfile.write("Hello, world!")

Handler = CustomHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)

print("Server started at port", PORT)
httpd.serve_forever()

在python3中自定义访问的根目录设置如下:

python -m http.server 8000  --directory C:/Users/59980/Desktop

2、BaseHTTPServer模块提供了更加底层的HTTP服务器实现,可以用于定制更复杂的HTTP服务器(目前python3.7以上不适用了):

import BaseHTTPServer

PORT = 8888

class CustomHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type','text/html')
        self.end_headers()
        self.wfile.write("Hello, world!")

try:
    httpd = BaseHTTPServer.HTTPServer(("", PORT), CustomHandler)
    print("Server started at port", PORT)
    httpd.serve_forever()
except KeyboardInterrupt:
    print("Server stopped")

保存为server.py,在命令行中执行python server.py即可启动一个HTTP服务器,访问http://localhost:8888将输出Hello, world!

BaseHTTPServer模块中的BaseHTTPRequestHandler类也提供了处理POST请求的方法do_POST,可以在其中处理POST请求的逻辑:

import BaseHTTPServer
import cgi

PORT = 8888

class CustomHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_POST(self):
        self.send_response(200)
        self.send_header('Content-type','text/html')
        self.end_headers()

        form = cgi.FieldStorage(
            fp=self.rfile,
            headers=self.headers,
            environ={'REQUEST_METHOD':'POST',
                     'CONTENT_TYPE':self.headers['Content-Type'],
                     })

        self.wfile.write("Hello, " + form['name'].value + "!")

try:
    httpd = BaseHTTPServer.HTTPServer(("", PORT), CustomHandler)
    print "Server started at port", PORT
    httpd.serve_forever()
except KeyboardInterrupt:
    print "Server stopped"

数值补齐:

1、字符串补齐:

ljust()方法将字符串靠左对齐,并用指定的字符(默认为空格)进行填充,使其总长度达到指定值。

rjust()方法将字符串靠右对齐,并用指定的字符进行填充,使其总长度达到指定值。

center()方法将字符串居中对齐,并用指定的字符进行填充,使其总长度达到指定值。

s = "Python"
result = s.ljust(10, '-')
print(result) # Python----
result = s.rjust(10, '*')
print(result) # ****Python
result = s.center(10, '+')
print(result) # ++Python++

2、数字补齐:

zfill()方法在数字的左侧用0进行填充,使其总长度达到指定值。

num = 123
result = str(num).zfill(6)
print(result) # 000123

3、格式化补齐:

s = "Python"
result = "{:<10}".format(s)  # 左对齐
print(result)

result = "{:>10}".format(s)  # 右对齐
print(result)

result = "{:^10}".format(s)  # 居中对齐
print(result)

 格式化数字补齐:

num = 123
result = "{:06d}".format(num)  # 数字左侧补0,总长度为6
print(result)

获取音频长度:

from pydub import AudioSegment
# 只能读取wav格式音频
audio_file = AudioSegment.from_file("audio.wav")
audio_length = len(audio_file)
print("音频长度为:", audio_length, "毫秒")

还可以使用Python的内置库wave来获取音频的长度:

import wave
# 只能获取wav音频
with wave.open(r"C:\Users\59980\Downloads\植物大战僵尸背景音乐.wav", "rb") as audio_file:
    audio_length = audio_file.getnframes() / audio_file.getframerate()
    # 音频的帧数 / 帧速率
    print("音频长度为:", audio_length, "秒")

获取指定格式文件路径:

用os模块来实现文件路径查找:筛选出所有以’.xlsx’结尾的文件路径

import os

# 指定文件夹路径
folder_path = 'C:/Users/59980/Desktop/新建文件夹/3月初盲审论文数据修正/实证结果/'

# 获取文件夹下所有文件和目录
files = os.listdir(folder_path)

# 指定文件格式
file_format = '.xlsx'

# 筛选特定格式的文件路径
for file in files:
    print(file)
    if file.endswith(file_format):
        file_path = os.path.join(folder_path, file)
        print(file_path)

"""
pearson.docx
pearson.xlsx
C:/Users/59980/Desktop/新建文件夹/3月初盲审论文数据修正/实证结果/pearson.xlsx
"""

除了os模块,还可以使用glob模块来获取指定格式文件的路径。glob模块提供了一个函数glob(),可以用来查找匹配指定模式的文件路径:

import glob

# 指定文件夹路径
folder_path = 'C:/Users/59980/Desktop/新建文件夹/3月初盲审论文数据修正/实证结果/'

# 指定文件格式
file_format = '*.xlsx'

# 使用glob模块获取文件路径
files = glob.glob(folder_path + file_format)

# 打印文件路径
for file in files:
    print(file)

ClickHouse关联交互:

ClickHouse是一个快速、高效的列式分布式数据库管理系统(一种OLAP类型的列式数据库管理系统),最初由Yandex开发。它支持高度并行的查询处理,能够处理PB级别的数据,并提供了灵活的数据模型。ClickHouse具有以下关键特点:

  • 列式存储:数据按列而非按行存储,有利于大规模数据的压缩和查询性能。
  • 并行处理:支持并行查询,可同时处理多个查询任务,提高查询速度。
  • 分布式架构:具备横向扩展的能力,可以在多台服务器上分布数据。
  • 优化查询引擎:通过使用高效的查询执行引擎提高性能,支持复杂的查询操作。

常见的MySQL、Oracle、SQL Server等数据库都是行式数据库,常见的列式数据库有hbase、clickhouse、Vertica等(存储内容一样,但存储方式不一样)。

 OLTP全称是On-line Transaction Processing,是一种联机事务型数据库,典型的数据库就是关系型数据库,OLTP关注的是对业务数据的增删改查,面向用户的事务操作,追求效率的最优解。

OLAP全称是On-Line Analytical Processing,是一种联机分析处理数据库,一般用于数据仓库或者大数据分析处理,这种类型的数据库在事务能力上很弱,但是在分析的场景下很强大,关键性的场景:

1、绝大多数是读请求

2、数据以相当大的批次(> 1000行)更新,而不是单行更新;或者根本没有更新。

3、已添加到数据库的数据不能修改。

4、对于读取,从数据库中提取相当多的行,但只提取列的一小部分。

5、宽表,即每个表包含着大量的列

6、查询相对较少(通常每台服务器每秒查询数百次或更少)

7、对于简单查询,允许延迟大约50毫秒

8、列中的数据相对较小:数字和短字符串(例如,每个URL 60个字节)

9、处理单个查询时需要高吞吐量(每台服务器每秒可达数十亿行)

10、事务不是必须的

11、对数据一致性要求低

12、每个查询有一个大表。除了他以外,其他的都很小。

13、查询结果明显小于源数据。换句话说,数据经过过滤或聚合,因此结果适合于单个服务器的RAM中。

clickhouse建表查询操作:

-- CREATE DATABASE [IF NOT EXISTS] db_name [ON CLUSTER cluster] [ENGINE = engine(...)]

CREATE DATABASE IF NOT EXISTS chtest;   --使用默认库引擎创建库

-- CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster](    name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [compression_codec] [TTL expr1],    name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2] [compression_codec] [TTL expr2],    ...) ENGINE = engine

node1 :) use default;
node1 :) create table test(id Int32,name String) engine=Memory; --内存引擎表
node1 :) insert into test(id,name) values(110,'test');   --字符串不能使用双引号
node1 :) select * from test;

-- 分布式DDL操作  默认情况下,CREATE、DROP、ALTER、RENAME操作仅仅在当前执行该命令的server上生效。

-- 创建一个分布式表   ON CLUSTER语句,这样就可以在整个集群发挥作用

CREATE TABLE IF NOT EXISTS user_cluster ON CLUSTER news_ck_cluster(
    id Int32, name String) ENGINE = Distributed(news_ck_cluster, default, user_local,id);



-- 表引擎   Distributed(cluster_name, database_name, table_name[, sharding_key])

1、创建分布式表是读时检查的机制,也就是说对创建分布式表和本地表的顺序并没有强制要求。

2、在上面的语句中使用了ON CLUSTER分布式DDL,这意味着在集群的每个分片节点上,都会创建一张Distributed表,这样便可以从其中任意一端发起对所有分片的读、写请求。

3、分布式表映射到每台服务器一张本地表。


# pip install clickhouse-driver
from clickhouse_driver import Client

client = Client('localhost', user='root', password='152617', database='stock_info',port=9000) # 建立与ClickHouse的连接 localhost是ClickHouse的主机地址

result = client.execute('SELECT * FROM stocks')

# 打印查询结果
for row in result:
    print(row)

# 关闭数据库连接
client.disconnect()

数据关联操作在实际应用中非常常见,尤其是在数据分析和数据处理领域。通过将不同数据集关联在一起,可以获取更多有用的信息和洞察。ClickHouse作为一个高性能的数据库系统,可以很好地支持这种关联操作。

在实际应用场景中,还可以使用更复杂的关联条件,如多表关联、多字段关联等。ClickHouse提供了丰富的SQL语法和函数,可以满足各种复杂的关联需求。

浮点数的存储

在计算机中,浮点数是以二进制形式存储的。由于浮点数需要同时表示整数部分和小数部分,因此采用IEEE 754标准来存储浮点数。在这个标准中,一个浮点数通常由三部分组成:符号位、指数位和尾数位。指数位用来表示浮点数的指数部分,尾数位用来表示浮点数的小数部分。

当我们将一个浮点数转换为十六进制表示时,实际上是将浮点数的二进制表示转换为十六进制表示。

import struct # 导入struct模块

def float_to_hex(f):
    return hex(struct.unpack('<I', struct.pack('<f', f))[0]) # 使用pack方法将浮点数转换为二进制表示


f = 3.14
print(float_to_hex(f)) # 用hex方法将二进制表示转换为十六进制表示

id()函数(对象的内存地址):

每个对象在内存中都有一个唯一的标识符,这个标识符可以帮助我们追踪对象的生命周期和使用情况

x = 10
print(id(x)) # 140733020460464  这个地址是一个十进制数

x = 10
y = x
print(id(x) == id(y))  # True

当对象没有被任何变量引用时,垃圾回收器会将其回收。这意味着对象的内存地址可能会在之后被重用。因此,id()函数返回的地址并不保证在整个程序执行过程中始终保持不变。

内存分析:通过id()函数,我们可以在内存中追踪对象的分配情况。可以用它来分析程序中是否存在内存泄漏或不必要的重复对象。

引用比较:有时,我们需要判断两个变量是否引用了同一个对象。这时可以使用id()函数来比较它们的内存地址。

数据结构中的应用:在一些自定义数据结构中,可能需要用到对象的内存地址作为键值来快速查找对象。这时可以利用id()函数来获取对象的地址。

生成HTML表格:

在HTML中,表格是由<table>元素定义的。表格中的数据通常是以行(<tr>)和列(<td><th>)的形式来排列的。其中,<td>用于表示普通的表格数据单元,<th>用于表示表头单元格。

用字符串拼接的方式来生成HTML表格:

def generate_html_table(data):
    css_style = "<style>table {width: 100%; border-collapse: collapse;} th, td {border: 1px solid black; padding: 8px;}</style>"
    # 添加样式
    html = "<table>"
    html += "<tr>"
    for header in data[0]:
        html += f"<th>{header}</th>"
    html += "</tr>"
    for row in data[1:]:
        html += "<tr>"
        for cell in row:
            html += f"<td>{cell}</td>"
        html += "</tr>"
    html += "</table>"
    return html

# 示例数据
data = [
    ["姓名", "年龄"],
    ["张三", 25],
    ["李四", 30]
]

html_table = generate_html_table(data)
print(html_table)

JSON对象更新:

创建一个简单的JSON对象(字典表示):

import json

# 创建一个JSON对象
student = {
    "name": "Alice",
    "age": 20,
    "major": "Computer Science"
}

# 将JSON对象转换为字符串
student_json = json.dumps(student)

print(student_json) # 字典形式

往JSON对象中添加新的元素时,可以将JSON对象转换为Python字典,然后向字典中添加新的键值对,最后将其转换回JSON格式:

# 将JSON字符串转换为Python字典
student_dict = json.loads(student_json)

# 添加新元素
student_dict["gender"] = "Female"

# 将字典转换为JSON字符串
updated_student_json = json.dumps(student_dict)

print(updated_student_json)

update()方法来更新JSON对象:

# 创建一个新的JSON对象
new_student = {
    "name": "Bob",
    "age": 22,
    "major": "Mathematics"
}

# 将JSON字符串转换为Python字典
student_dict = json.loads(student_json)

# 更新JSON对象
student_dict.update(new_student)

# 将字典转换为JSON字符串
updated_student_json = json.dumps(student_dict)

print(updated_student_json)

json.loads()方法将JSON字符串转换为Python字典,然后通过操作字典来添加、更新、删除元素,最后使用json.dumps()方法将字典转换回JSON格式

读取日志获取每行数据并自动关闭文件:

log_file_path = 'example.log'

with open(log_file_path, 'r') as file:
    for line in file:# 获取每一行
        # 解析日志数据
        timestamp, level, message = line.split(' ', 2)

        # 输出日志数据
        print(f'Timestamp: {timestamp}, Level: {level}, Message: {message}')

大写转小写:

# 使用 lower() 方法将大写字母转换为小写字母
s_lower = s.lower()


# 循环大写转小写
# 定义一个包含大写字母的字符串
s = "HELLO WORLD"
s_lower = ""

for char in s:
    if ord('A') <= ord(char) <= ord('Z'):
        char_lower = chr(ord(char) + 32)  # 大写转小写的 ASCII 编码
    else:
        char_lower = char
    s_lower += char_lower

print(s_lower)

 判断是不是数字:

1、type()函数

# 判断整数
num1 = 10
print(type(num1) is int)  # True

# 判断浮点数
num2 = 3.14
print(type(num2) is float)  # True

# 判断复数
num3 = 1j
print(type(num3) is complex)  # True

2、isinstance()函数:接受一个类型(如int、float、complex)或一个类型的元组作为参数

# 判断整数
num1 = 10
print(isinstance(num1, int))  # True

# 判断浮点数
num2 = 3.14
print(isinstance(num2, float))  # True

# 判断复数
num3 = 1j
print(isinstance(num3, complex))  # True

3、正则表达式

import re

# 判断整数
num1 = '123'
print(bool(re.match(r'^[0-9]+', num1)))  # True

# 判断浮点数
num2 = '3.14'
print(bool(re.match(r'^[0-9]+.[0-9]+', num2)))  # True

# 判断复数
num3 = '1j'
print(bool(re.match(r'^[0-9]+[+|-]*[0-9]*j$', num3)))  # True

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值