Python_一些解决方法

基础应用

动态循环输出文字

print() 打印时会自动换行,无法实现刷新后在原位置显示内容,而 sys.stuout.write() 方法打印输出的时候自动删除前一步打印输出的内容,从而实现文字的循环动态显示

# _*_coding : UTF-8 _*_
import sys
import time

def print_arc(word):
    # 让光标回到行首
    sys.stdout.write('\r')
    # 缓冲区的数据全部输出
    sys.stdout.flush()
    for item in word:
        sys.stdout.write(item)
        sys.stdout.flush()
        time.sleep(0.1)

while True:
    print_arc('VISITANTES   VISITANTES')

检索敏感词并描出标红

显示方式: 0(默认值)、1(高亮)、22(非粗体)、4(下划线)、24(非下划线)、 5(闪烁)、25(非闪烁)、7(反显)、27(非反显)
前景色: 30(黑色)、31(红色)、32(绿色)、 33(黄色)、34(蓝色)、35(洋 红)、36(青色)、37(白色)
背景色: 40(黑色)、41(红色)、42(绿色)、 43(黄色)、44(蓝色)、45(洋 红)、46(青色)、47(白色)

\033[0m 默认字体正常显示,不高亮
\033[32;1m 红色字体正常显示,高亮

# _*_coding : UTF-8 _*_
word = input('请输入含有敏感词的宣传文字:\n')
sensitive = ['第一', '国家级', '仅此一次']
sensitive_find = []
newword = word
for item in sensitive:
    if word.count(item) > 0:
        sensitive_find.append(item + ':' + str(word.count(item)) + '次')
        newword = newword.replace(item, '\033[1;31m' + item + '\033[0m')
print('发现敏感词如下:')
for item in sensitive_find:
    print(item)
print('敏感词位置已标红:\n' + newword)

利用 lambda 简化编程

  1. os.listdir(root_path) 出现乱序问题 或 不区分大小写排序

    filename = os.listdir(root_path)
    filename.sort(key=lambad x:int(x.split('_')[0]))
    
    char = ['cat', 'Tom', 'Angela', 'pet']
    print(char.sort(key=str.lower)) # ['Angela', 'cat', 'pet', 'Tom']
    
  2. 过滤指定后缀名 ('.png') 的文件 或 取余数

    filename = os.listdir(root_path)
    filename = list(filter(lambda x: x.endswith('.png'), filename))
    
    listx = [3,21,5,27,17]
    print(filter(lambda x: x % 7 == 0, listx))
    
  3. 对每一个元素进行共同操作

    list_num = [1,2,3,4]
    print(list(map(lambda x:x*x,list_num))) # [1, 4, 9, 16]
    
  4. 判断大小

    num = '135749'
    print(max(num, key=lambda x:abs(int(x)))) # 9
    

清洗字符串

strip() 可以默认删除字符串头和尾的空白字符(包括\n,\r,\t 等)

# 去掉空格
word = '赵 钱 孙 李'
word = ''.join([i.strip(' ') for i in word if i != ''])
print(word) #赵钱孙李

字符串与列表去重

  • 字符串去重
  1. 通过for循环遍历字符串去重

    name = '赵孙钱李周吴孙李郑王'
    newname = ''
    for char in name:
        if char not in newname:
            newname += char
    print(newname) # 赵孙钱李周吴郑王
    
  2. 使用列表的方法去重

    name = '赵孙钱李周吴孙李郑王'
    newname = list(set(name))
    print(''.join(newname)) # 吴郑王孙李赵周钱(随机排序)
    # index() 获取指定元素在列表中首次出现的位置
    newname.sort(key=name.index)
    newname = ''.join(newname)
    print(newname) # 赵孙钱李周吴郑王
    
  3. 在原字符串中直接删除

    name = '赵孙钱李周吴孙李郑王'
    l = len(name)
    for s in name:
        if name[0] in name[1:l]:
            name = name[1:l]
        else:
            name = name[1:l] + name[0]
    print(name) # 赵孙钱李周吴郑王
    
  4. 使用 fromkeys() 方法把字符串转换成字典

    name = '赵孙钱李周吴孙李郑王'
    zd = {}.fromkeys(name)
    print(zd) # {'赵': None, '孙': None, '钱': None, '李': None, '周': None, '吴': None, '郑': None, '王': None}
    mylist = ''.join(list(zd.keys()))
    print(mylist) # 赵孙钱李周吴郑王
    
  • 列表去重
  1. for循环

    city = ['bj', 'sh','bj', 'gz', 'sz', 'gz']
    ncity = []
    for item in city:
        if item not in ncity:
            ncity.append(item)
    print(ncity) # ['bj', 'sh', 'gz', 'sz']
    
  2. set方法

    city = ['bj', 'sh','bj', 'gz', 'sz', 'gz']
    ncity = list(set(city))
    ncity.sort( key=city.index)
    print(ncity) # ['bj', 'sh', 'gz', 'sz']
    
  3. count() 方法统计并删除,需要先排序

    city = ['bj', 'sh','bj', 'gz', 'sz', 'gz']
    city.sort()
    for x in city:
        while city.count(x)>1:
            del city[city.index((x))]
    print(city) # ['bj', 'gz', 'sh', 'sz']
    
  4. 把列表转换成字典

    city = ['bj', 'sh','bj', 'gz', 'sz', 'gz']
    mylist = {}.fromkeys(city).keys()
    print(mylist) # dict_keys(['bj', 'sh', 'gz', 'sz'])
    mylist = list(mylist)
    print(mylist) # ['bj', 'sh', 'gz', 'sz']
    

map/reduce/filter

map()

  • 第一个参数是 f,即函数对象 本身
  • 第二个是 Iterable (可迭代对象),map 将传入的函数依次作用到序列的每个元素,并把结果作为新的 Iterable 返回

reduce()

  • 第一个参数是 f,即函数对象 本身,这个函数必须接受两个参数
  • 第二个是 Iterable (序列),把一个函数作用在一个序列上,reduce 把结果继续和序列的下一个元素做累积计算

filter

  • 第一个参数是 f,即函数对象 本身
  • 第二个是 Iterable (可迭代对象),和 map 不同的是,filter 把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素
>>> a = [1,2,3,4,5,6,7,8]
>>> def mult(x):
	return x * 10
>>> b = map(mult, a)
>>> list(b)
[10, 20, 30, 40, 50, 60, 70, 80]

>>> num = [2,3,5]
>>> ','.join(map(str, num))
'2,3,5'
>>> list(map(str, num))
['2', '3', '5']

##############################

>>> from functools import reduce
>>> c = reduce(add, a)
>>> c
36

##############################

>>> def is_odd(n):
    return n % 2 == 1
>>> d = [1, 2, 4, 5, 6, 9, 10, 15]
>>> e = filter(is_odd, d)
>>> list(e)
[1, 5, 9, 15]

zip/zifill/rindex

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

zfill() 方法返回指定长度的字符串,原字符串右对齐,前面填充0

rindex() 返回子字符串 str 在字符串中最后出现的位置,如果没有匹配的字符串会报异常

>>> import numpy as np
>>> arr = np.arange(6).reshape(2,3)
>>> arr
array([[0, 1, 2],
       [3, 4, 5]])
# 使用numpy对二维数组转置
>>> arr.T
array([[0, 3],
       [1, 4],
       [2, 5]])

>>> arr2 = np.arange(3)
>>> arr2
array([0, 1, 2])
>>> arr3 = np.arange(3,6)
>>> arr3
array([3, 4, 5])
# 使用zip进行逆操作
>>> list(zip(arr2,arr3))
[(0, 3), (1, 4), (2, 5)]
>>> list(zip(*arr))
[(0, 3), (1, 4), (2, 5)]

>>> str1 = 'testzfill'
>>> len(str1)
9
>>> str1.zfill(11)
'00testzfill'

>>> str1.rindex('z')
4

time.csv

计算机常用字符集编码详解

GB18030编码向下兼容GBK和GB2312,兼容的含义是不仅字符兼容,而且相同字符的编码也相同

import pandas as pd
import time
df = pd.read_csv(r'C:\Users\Desktop\time.csv', encoding='gb18030')
print(df.groupby('视频名称').size())
def get_seconds(time):
    h, m, s = [int(t) for t in time.split(':')]
    return h*60*60 + m*60 + s
for video, group in df.groupby('视频名称'):
    start_end_list = sorted(list(zip(list(group['ID']),
                        [get_seconds(i)for i in list(group['开始时间'])],
                        [get_seconds(i)for i in list(group['结束时间'])])),key=lambda y:y)
    print(start_end_list)

更推荐的使用方法

  1. os.scandir() 获取文件路径及详细信息

    os.stat()

    • st_atime :文件最近的访问时间,Unix时间戳,可利用 ctime() 转换成正常时间,也可以用 datetime.datetime.fromtimestamp() 转换
    • st_mtime :文件的最近修改时间,Unix时间戳,可利用 ctime() 转换成正常时间,也可以用 datetime.datetime.fromtimestamp() 转换
    • st_size :文件的体积大小(bytes),除以1024就是KB
  2. os.walk() :输出文件夹路径和文件名称

  3. glob.glob() :匹配文件

  4. enumerate():有一个元素列表,您需要遍历列表,同时访问索引和值

  5. 使用set存储唯一值

  6. 使用生成器节省内存

  7. 使用collections.Counter计算Hashable对象

哈希表与哈希值

可哈希对象与不可哈希对象

  • 可哈希数据类型,即不可变的数据类型(数字类型(int、float、bool)、字符串str、元组tuuple、自定义的对象)
  • 不可哈希数据类型,即可变的数据结构(字典dict、列表list、集合set)

random.choice(sequence) 从序列中获取一个随机元素

random.sample(sequence, k) 从序列中获取指定个数的随机元素

  • list,tuple,str 都属于sequence
import os
import glob
import datetime
import random
import time
from collections import Counter

root_path = input('请输入文件夹地址:')

for file in os.scandir(root_path):
    print(file.name, file.path, file.is_dir())
    print(datetime.datetime.fromtimestamp(file.stat().st_atime))
print('next'.center(20,'-'))

# dirnames 是dirpath这个文件夹下的子文件夹列表
for dirpath, dirnames, files in os.walk(root_path):
    for file in files:
        print(f'发现文件:{file}')
    print(f'发现文件夹:{dirpath}')
print('next'.center(20,'-'))

# ** 匹配任意数量的字符包括空字符(包括路径分隔符)
print(glob.glob(root_path+'/**/*.jpg', recursive=True))
print('next'.center(20,'-'))

# 把可遍历的列表组合为索引序列,从1开始计数
dir_list = os.listdir(root_path)
for (index, dir_name) in enumerate(dir_list, start=1):
    print(index, dir_name)
print('next'.center(20,'-'))

# 集合存储元素的方式允许接近恒定时间检查值是否在集合中,而不像需要线性时间查找的列表
# 如果使用列表 随着单词数量的增加,查找次数呈二次方式增长,时间复杂度在O(N^2)
all_words = "all the words in the world".split()
def get_random_word():
    return random.choice(all_words)
def get_unique_words():
    words = set()
    for _ in range(1000):
        words.add(get_random_word())
    return words
print(get_unique_words())
print('next'.center(20,'-'))

# 生成器表达式返回生成器对象,而不是创建列表。该对象知道它在当前状态的位置并且仅在要求时计算下一个值
start_time = time.time()
sum([i * i for i in range(1, 1000000)])
end_time = time.time()
print('listing comprehension:{}ms'.format(round((end_time-start_time)*1000,2)))
start_time = time.time()
sum((i * i for i in range(1, 1000000)))
end_time = time.time()
print('generator:{}ms'.format(round((end_time-start_time)*1000,2)))
print('next'.center(20,'-'))

# Count是dict的子类,它使用0作为任何缺失元素的默认值,并且更容易计算对象的出现次数
words = "if there was there was but if there was not there was not".split()
counts = Counter(words)
print(counts)

创建临时文件

with…as…:不管程序是否正常运行都会关闭文件,不需要再单独写close()

# 创建临时文件和临时文件夹
from tempfile import TemporaryFile
from tempfile import TemporaryDirectory
# w+ 表示写入及读取文件
with TemporaryFile('w+') as f:
    f.write('你好HELLO')
    # seek(0) 回到文件开头位置
    f.seek(0)
    data = f.readlines()
    print(data)
with TemporaryDirectory as tmp_folder:
    print(f'临时文件夹已经创建:{tmp_folder}')

创建压缩包/解压缩

import zipfile
import os
# 解压缩/读取压缩包信息
with zipfile.ZipFile('done.zip', 'r') as zipobj:
    for filename in zipobj.namelist():
        info = zipobj.getinfo(filename)
        new_filename = filename.encode('cp437').decode('gbk')
        print(new_filename, info.compress_size)
    zipobj.extractall('done')
# 创建压缩包
with zipfile.ZipFile('do.zip', 'w') as zipobj:
    file_list = os.listdir()
    for file in file_list:
        zipobj.write(file)

文件读写

  1. codecs

    TypeError: an integer is required (got type str)

    open打开文件只能写入str类型,不管字符串是什么编码方式

    但是有时候我们爬虫或者其他方式得到一些数据写入文件时会有编码不统一的问题,所以就一般都统一转换为unicode,我们要把得到的东西先decode为unicode再encode为str

    代替这繁琐操作就是codecs.open

    import  codecs
    fr = open('test.txt','a')
    fw = codecs.open('test.txt','a','utf-8')
    
  2. pickle

    pickle 是一个 python 中, 压缩/保存/提取 文件的模块

    字典和列表都是能被保存的

    import pickle
    
    a_dict = {'da': 111, 2: [23,1,4], '23': {1:2,'d':'sad'}}
    
    file = open('pickle_example.pickle', 'wb')
    pickle.dump(a_dict, file)
    file.close()
    
    with open('pickle_example.pickle', 'rb') as file:
        a_dict1 = pickle.load(file)
    
    print(a_dict1)
    
  3. csv
    如果csv第一行没有索引,需要指定索引,可用names=index 指定
    csv没有首行

    df_csv = pd.read_csv(csv_path)
    df_index = ['frame','ID','x1','y1','x2','y2','keyframe1','cate','keyframe2']
    df_csv = pd.read_csv(csv_path, header=0,names=df_index)
    ID = df_csv['ID'].values.tolist()
    cate = df_csv['cate'].values.tolist()
    ID_dict = {}
    for i in range(len(ID)):
    	ID_dict[ID[i]] = cate[i]
    

sys模块

Python常用标准库之sys:https://www.jianshu.com/p/c1831232c391

sys.argv[1] 获取命令行传入的第一个数据

sys.stdin 获取输入内容

sys.stdout.flush() 刷新输出

sys.stdout.write() 打印输出内容

import sys
import time

# 无限获取键盘输入 方法1
while True:
    line = sys.stdin.readline().strip()
    if line == '':
        break
    a = line.split()
    print(sys.argv)
    print(int(a[0]) + int(a[1]))

# 无限获取键盘输入 方法2
for line in sys.stdin:
    a = line.split()
    if not a:
        break
    print(sys.argv)
    print(int(a[0]) + int(a[1]))

# 不换行输出
for i in range(20):
    print("\r", end="")
    print(f'{i} 行', end="")
    sys.stdout.flush()
    time.sleep(1)

# 打印速度
for i in range(0, int(1e5+1)):
    rate = int(i / 1e5 * 100)
    r = f'\r当前进度:{"="*(2*rate//10)+">"}{" "*(20-2*rate//10)}{rate}%'
    
    sys.stdout.write(r)
    sys.stdout.flush()
    # 上下这两个等价
    print(r, end="")

解析xml文件

格式

  1. ElementTree

    参考

    修改XML

    • ElementTree.write()将构建的XML文档写入文件。
    • Element.text = ‘’ 直接改变字段内容
    • Element.append(Element) 为当前的Elment对象添加子对象
    • Element.remove(Element) 删除Element节点
    • Element.set(key, value) 添加和修改属性
    • ElementTree.write(‘filename.xml’) 写出(更新)XMl文件
    import xml.etree.ElementTree as ET
    tree = ET.parse('1.xml')
    for track in tree.findall('track'):
        track_attr = track.attrib
        # print(track_attr['label'])
        for box in track.findall('box'):
            box_attr = box.attrib
            if box_attr['outside'] == '0':
                print(box_attr['xtl'],box_attr['ytl'],box_attr['xbr'],box_attr['ybr'])
            for attr in box.findall('attribute'):
                attr_attr = attr.attrib
                attr_cate = attr.text
                print(attr_attr,attr_cate)
    
  2. untangle

    参考

    • 同一个名字的兄弟元素组成数组
    • 通过parent.child访问子元素,通过element[‘attribute’]访问属性
    • 使用parse()方法处理xml文件,URL或者是xml字符串
    import untangle
    obj = untangle.parse('2.xml')
    for track in obj.annotations.track:
      print(track['label'])
      for box in track.box:
        print(box['xtl'],box['ytl'],box['xbr'],box['ybr'])
        for att in box.attribute:
          print(att['name'])
          print(att.cdata)
    

深拷贝和浅拷贝

深拷贝、浅拷贝

>>> import copy
# 如果拷贝的是可变类型的数据,copy是浅拷贝,deepcopy是深拷贝,都不是指向
>>> a = [11,22]
>>> b = [33,44]
>>> c = [a,b]
>>> id(c)
2150737753352
>>> d = copy.copy(c)
>>> id(d)
2150737827720
>>> e = copy.deepcopy(c)
>>> id(e)
2150737752968
>>> c.append([55,66])
>>> c
[[11, 22], [33, 44], [55, 66]]
>>> d
[[11, 22], [33, 44]]
>>> e
[[11, 22], [33, 44]]

# 赋值语句是指向
>>> f = a
>>> id(f)
2150737828232
>>> id(a)
2150737828232

# 如果copy.copy和copy.deepcopy对一个全部都是不可变类型的数据进行拷贝,那么它们不会进行拷贝,仅仅是指向
>>> a = (11,22)
>>> b = copy.copy(a)
>>> id(a)
2150737405256
>>> id(b)
2150737405256
>>> c = copy.deepcopy(a)
>>> id(c)
2150737405256

# 如果拷贝的是一个拥有不可变类型的数据,即使元祖是最顶层,那么deepcopy仍然是深拷贝,而copy还是指向
>>> a = [11,22]
>>> b = [33,44]
>>> c = (a,b)
>>> d = copy.copy(c)
>>> id(c)
2150737405320
>>> id(d)
2150737405320
>>> e = copy.deepcopy(c)
>>> id(e)
2150737829320

异常处理

Python assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常

断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况

>>> assert True     # 条件为 true 正常执行
>>> assert False    # 条件为 false 触发异常

root_path = input('请输入 json 所在地址:')
cat= [...]

# try...except
try:
    file = '1.json'
    json_path = os.path.join(root_path, file)
    json_data = codecs.open(json_path, 'r', 'utf-8')
    json_data = json.load(json_data)
    category = json_data['category']
    attributes = json_data['category']
except FileNotFoundError:
	print('地址输入错误,请检查地址'.center(20,'-'))

for key, value in attributes.items():
    # isinstance() 会认为子类是一种父类类型,考虑继承关系
	if isinstance(value, bool):
		continue
	# raise 引发一个异常
	if category not in cat:
		raise Exception(f'Categeory not in Excel {category}')

WPS处理

Excel——openpyxl

from openpyxl import load_workbook
# 读取表格
workbook = load_workbook(r'dir_list.xlsx')
sheet = workbook.active
for row in range(1,sheet.max_row+1):
    for col in range(1,sheet.max_column+1):
        cel = sheet.cell(row,col)
        val = cel.value
        if isinstance(val, str):
            if val.endswith('.jpg'):
                cor = sheet.cell(row,col).coordinate
                print(cel, cor)

from openpyxl import Workbook
#生成Excel文件
# os.chdir(path1)
wb = Workbook()
ws = wb.active
ws.title = 'json'
first_row = []
datas = []
oufile = './labels_num.txt'
with open(outfile,encoding='utf-8') as f:
    is_first_row = True
    for line in f:
        line = line[:-1]
        #存储第一行
        if is_first_row:
            is_first_row = False
            first_row = line.split('\t')
            continue
        #存储第二行至max_row
        datas.append(line.split('\t'))
ws.append(first_row)
for data in datas:
    ws.append(data)
excel_outfile = './labels_num.xlsx'
wb.save(excel_outfile)

Excel——xlrd/xlwt

import xlrd
import sys
workbook = xlrd.open_workbook(sys.argv[1])
worksheet = workbook.sheets()[0]
for row in range(worksheet.nrows):
    for col in range(worksheet.ncols):
        cel = worksheet.cell(row, col)
        val = cel.value
        print(val)

########################################

import os
import xlwt
file_dir = input('请输入地址:')
filename = os.listdir(file_dir)
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('filename')
n = 0
for i in filename:
    worksheet.write(n, 0, i)
    n += 1
workbook.save(sys.argv[1])
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值