技术标签: python3版本代码大全
出品 | FlyAI
编译 | 林椿眄
编辑 | Donna
Python 已经成为机器学习及其他科学领域中的主流语言。它不但与多种深度学习框架兼容,而且还包含优秀的工具包和依赖库,方便我们对数据进行预处理和可视化操作。
据最新消息,到2019 年底,Numpy 等很多科学计算工具包都将停止支持Python 2版本,而 2018 年后 Numpy 的所有新功能版本也都将只支持 Python 3。
为了使初学者能够轻松地从 Python 2 向 Python 3 实现迁移,我收集了一些 Python 3 的功能,希望对大家有所帮助。
使用 pathlib 模块来更好地处理路径
pathlib 是 Python 3默认的用于处理数据路径的模块,它能够帮助我们避免使用大量的 os.path.joins语句:
from pathlib import Path dataset = 'wiki_images'datasets_root = Path('/path/to/datasets/') train_path = datasets_root / dataset / 'train'test_path = datasets_root / dataset / 'test'for image_path in train_path.iterdir(): with image_path.open() as f: # note, open is a method of Path object # do something with an image
在Python2中,我们需要通过级联字符串的形成来实现路径的拼接。而现在有了pathlib模块后,数据路径处理将变得更加安全、准确,可读性更强。
此外,pathlib.Path含有大量的方法,这样Python的初学者将不再需要搜索每个方法:
p.exists() p.is_dir() p.parts() p.with_name('sibling.png') # only change the name, but keep the folderp.with_suffix('.jpg') # only change the extension, but keep the folder and the namep.chmod(mode)p.rmdir()
使用pathlib还将大大节约你的时间。更多功能请查看:
官方文档 - https://docs.python.org/3/library/pathlib.html参考信息 - https://pymotw/3/pathlib/
类型提示(Type hinting)成为Python3中的新成员
下面是在编译器PyCharm 中,类型提示功能的一个示例:
Python 不只是一门脚本的语言,如今的数据流程还包括大量的逻辑步骤,每一步都包括不同的框架(有时也包括不同的逻辑)。
Python3中引入了类型提示工具包来处理复杂的大型项目,使机器可以更好地对代码进行验证。而在这之前,不同的模块需要使用自定义的方式,对文档中的字符串指定类型 (注意:PyCharm可以将旧的文档字符串转换成新的类型提示)。
下面是一个简单的代码示例,利用类型提示功能来处理不同类型的数据:
def repeat_each_entry(data): """ Each entry in the data is doubled """ index = numpy.repeat(numpy.arange(len(data)), 2) return data[index]
上述代码对多维的 numpy.array、astropy.Table 和 astropy.Column、bcolz、cupy、mxnet.ndarray 等操作同样适用。
这段代码还可用于 pandas.Series 操作,但是这种形式是错误的:
repeat_each_entry(pandas.Series(data=[0, 1, 2], index=[3, 4, 5])) # returns Series with Nones inside
这仅仅是一段两行的代码。所以,复杂系统的行为是非常难预测的,有时一个函数就可能导致整个系统的错误。因此,明确地了解哪些类型方法,并在这些类型方法未得到相应参数的时候发出错误提示,这对于大型系统的运作是很有帮助的。
def repeat_each_entry(data: Union[numpy.ndarray, bcolz.carray]):
如果你有一个很棒的代码库,诸如 MyPy这样的类型提示工具将可能成为一个大型项目的集成流程中的一部分。不幸的是,类型提示功能还没办法强大到为 ndarrays/tensors 这种细粒度类型发出提示。或许,不久的将来我们就可以拥有这样全面的的类型提示工具,这将成为数据科学领域需要的强大功能。
从类型提示(运行前)到类型检查(运行时)
默认情况下,函数的注释对于代码的运行是没有影响的,它只是帮你指出每段代码所要做的工作。
在代码运行阶段,很多时候类型提示工具是不起作用的。这种情况你可以使用 enforce 等工具,强制性对代码进行类型检查,同时也可以帮助你调试代码。
@enforce.runtime_validationdef foo(text: str) -> None: print(text) foo('Hi') # okfoo(5) # [email protected]_validationdef any2(x: List[bool]) -> bool: return any(x)any ([False, False, True, False]) # Trueany2([False, False, True, False]) # Trueany (['False']) # Trueany2(['False']) # failsany ([False, None, "", 0]) # Falseany2([False, None, "", 0]) # fails
函数注释的其他用途
正如上面我们提到的,函数的注释部分不仅不会影响代码的执行,还会提供可以随时使用的一些元信息(meta-information)。
例如,计量单位是科学界的一个普遍难题,Python3中的astropy包提供了一个简单的装饰器(Decorator)来控制输入的计量单位,并将输出转换成相应的单位。
# Python 3from astropy import units as [email protected]_input()def frequency(speed: u.meter / u.s, wavelength: u.m) -> u.terahertz: return speed / wavelength frequency(speed=300_000 * u.km / u.s, wavelength=555 * u.nm)# output: 540.5405405405404 THz, frequency of green visible light
如果你需要用Python处理表格类型的科学数据,你可以尝试astropy包,体验一下计量单位随意转换的方便性。你还可以针对某个应用专门定义一个装饰器,用同样的方式来控制或转换输入和输出的计量单位。
通过 @ 实现矩阵乘法
下面,我们实现一个最简单的机器学习模型,即带 L2 正则化的线性回归 (如岭回归模型),来对比 Python2 和 Python3 之间的差别:
# l2-regularized linear regression: || AX - b ||^2 + alpha * ||x||^2 -> min# Python 2X = np.linalg.inv(np.dot(A.T, A) + alpha * np.eye(A.shape[1])).dot(A.T.dot(b))# Python 3X = np.linalg.inv(A.T @ A + alpha * np.eye(A.shape[1])) @ (A.T @ b
在 Python3 中,以@作为矩阵乘法符号使得代码整体的可读性更强,且更容易在不同的深度学习框架间进行转译:因为一些代码如 X @ W + b[None, :]在 numpy、cupy、pytorch 和 tensorflow 等不同库中都表示单层感知机。
使用 ** 作为通配符
Python2 中使用递归文件夹的通配符并不是很方便,因此可以通过定制的 glob2 模块来解决这个问题。递归 flag 在 Python 3.6 中得到了支持。
import glob# Python 2found_images = \ glob.glob('/path*.jpg') \ + glob.glob('/path*.jpg') \ + glob.glob('/path***.jpg') # Python 3found_images = glob.glob('/path*.jpg', recursive=True)
Python3 中更好的选择是使用 pathlib:(缺少个import)
# Python 3found_images = pathlib.Path('/path/').glob('**/*.jpg')
Python3中的print函数
诚然,print 在 Python3 中是一个函数,使用 print 需要加上圆括弧(),虽然这是个麻烦的操作,但它还是具有一些优点:
使用文件描述符的简单句法:
print >>sys.stderr, "critical error" # Python 2print("critical error", file=sys.stderr) # Python 3
在不使用str.join情况下能够输出 tab-aligned 表格:
# Python 3print(*array, sep='\t')print(batch, epoch, loss, accuracy, time, sep='\t')
修改与重新定义 print 函数的输出:
# Python 3_print = print # store the original print functiondef print(*args, **kargs): pass # do something useful, e.g. store output to some file
在 Jupyter notebook 中,这种形式能够记录每一个独立的文档输出,并在出现错误的时候追踪到报错的文档。这能方便我们快速定位并解决错误信息。因此我们可以重写 print 函数。
在下面的代码中,我们可以使用上下文管理器来重写 print 函数的行为:
@contextlib.contextmanagerdef replace_print(): import builtins _print = print # saving old print function # or use some other function here builtins.print = lambda *args, **kwargs: _print('new printing', *args, **kwargs) yield builtins.print = _printwith replace_print():
但是,重写print函数的行为,我们并不推荐,因为它会引起系统的不稳定。
print函数可以结合列表生成器或其它语言结构一起使用。
# Python 3result = process(x) if is_valid(x) else print('invalid item: ', x)
f-strings 可作为简单和可靠的格式化
默认的格式化系统提供了一些灵活性操作。但在数据实验中这些操作不仅不是必须的,还会导致代码的修改变得冗长和琐碎。
而数据科学通常需要以固定的格式,迭代地打印出一些日志信息,所使用的代码如下:
# Python 2print('{batch:3} {epoch:3} / {total_epochs:3} accuracy: {acc_mean:0.4f}±{acc_std:0.4f} time: {avg_time:3.2f}'.format( batch=batch, epoch=epoch, total_epochs=total_epochs, acc_mean=numpy.mean(accuracies), acc_std=numpy.std(accuracies), avg_time=time / len(data_batch) ))# Python 2 (too error-prone during fast modifications, please avoid):print('{:3} {:3} / {:3} accuracy: {:0.4f}±{:0.4f} time: {:3.2f}'.format( batch, epoch, total_epochs, numpy.mean(accuracies), numpy.std(accuracies), time / len(data_batch) ))
样本输出为:
120 12 / 300 accuracy: 0.8180±0.4649 time: 56.60
Python 3.6 中引入了格式化字符串 (f-strings):
f# Python 3.6+print(f'{batch:3} {epoch:3} / {total_epochs:3} accuracy: {numpy.mean(accuracies):0.4f}±{numpy.std(accuracies):0.4f} time: {time / len(data_batch):3.2f}')
另外,这对于查询语句的书写也是非常方便的:
query = f"INSERT INTO STATION VALUES (13, '{city}', '{state}', {latitude}, {longitude})"
「true pision」和「integer pision」之间的明显区别
虽然说对于系统编程来说,Python3所提供的改进还远远不够,但这些便利对于数据科学来说已经足够。
data = pandas.read_csv('timing.csv') velocity = data['distance'] / data['time']
Python 2 中的结果依赖于『时间』和『距离』(例如,以米和秒为单位),关注其是否被保存为整数。
而在 Python 3 中,结果的表示都是精确的,因为除法运算得到的都是精确的浮点数。
另一个例子是整数除法,现在已经作为明确的运算:
n_gifts = money // gift_price # correct for int and float arguments
值得注意的是,整除运算可以应用到Python的内建类型和由numpy、pandas等数据包提供的自定义类型。
严格排序
下面是一个严格排序的例子:
# All these comparisons are illegal in Python 33 < '3'2 < None(3, 4) < (3, None)(4, 5) < [4, 5]# False in both Python 2 and Python 3(4, 5) == [4, 5]
严格排序的主要功能有:
防止不同类型实例之间的偶然性排序。
sorted([2, '1', 3]) # invalid for Python 3, in Python 2 returns [2, 3, '1']
在处理原始数据时帮助我们发现存在的问题。此外,严格排序对None值的合适性检查是(这对于两个版本的 Python 都适用):
if a is not None: passif a: # WRONG check for None pass
自然语言处理中的Unicode编码
下面来看一个自然语言处理任务:
s = '您好'print(len(s))print(s[:2])
比较两个版本Python的输出:
Python2: 6\n
Python3: 2\n 您好
再来看个例子:
x = u'со' x += 'co' # ok x += 'со' # fail
在这里,Python 2 会报错,而 Python 3 能够正常工作。因为我在字符串中使用了俄文字母,对于Python2 是无法识别或编码这样的字符。
Python 3 中的 strs 是 Unicode 字符串,这对非英语文本的自然语言处理任务来说将更加地方便。还有些其它有趣的应用,例如:
'a'< type < u'a' # Python 2: True'a' < u'a' # Python 2: False
from collections import Counter Counter('Mbelstück')
Python 2: Counter({'\xc3': 2, 'b': 1, 'e': 1, 'c': 1, 'k': 1, 'M': 1, 'l': 1, 's': 1, 't': 1, '\xb6': 1, '\xbc': 1})
Python 3: Counter({'M': 1, '': 1, 'b': 1, 'e': 1, 'l': 1, 's': 1, 't': 1, 'ü': 1, 'c': 1, 'k': 1})
对于这些,Python 2 也能正常地工作,但 Python 3 的支持更为友好。
保留词典和**kwargs 的顺序
CPython 3.6+ 的版本中字典的默认行为是一种类似 OrderedDict 的类,但最新的 Python3.7 版本,此类已经得到了全面的支持。这就要求在字典理解、json 序列化/反序列化等操作中保持字典原先的顺序。
下面来看个例子:
import json x = {str(i):i for i in range(5)} json.loads(json.dumps(x))# Python 2{u'1': 1, u'0': 0, u'3': 3, u'2': 2, u'4': 4}# Python 3{'0': 0, '1': 1, '2': 2, '3': 3, '4': 4}
这种保顺性同样适用于 Python3.6 版本中的 **kwargs:它们的顺序就像参数中显示的那样。当设计数据流程时,参数的顺序至关重要。
以前,我们必须以这样繁琐的方式来编写:
from torch import nn # Python 2 model = nn.Sequential(OrderedDict([ ('conv1', nn.Conv2d(1,20,5)), ('relu1', nn.ReLU()), ('conv2', nn.Conv2d(20,64,5)), ('relu2', nn.ReLU()) ])) # Python 3.6+, how it *can* be done, not supported right now in pytorch model = nn.Sequential( conv1=nn.Conv2d(1,20,5), relu1=nn.ReLU(), conv2=nn.Conv2d(20,64,5), relu2=nn.ReLU()) )
注意到了吗?名称的唯一性也会被自动检查。
迭代拆封
Python3 中引入迭代式拆封功能,下面来看一段代码:
# handy when amount of additional stored info may vary between experiments, but the same code can be used in all casesmodel_paramteres, optimizer_parameters, *other_params = load(checkpoint_name)# picking two last values from a sequence*prev, next_to_last, last = values_history# This also works with any iterables, so if you have a function that yields e.g. qualities,# below is a simple way to take only last two values from a list *prev, next_to_last, last = iter_train(args)
默认的 pickle 引擎为数组提供更好的压缩
Python3 中引入 pickle 引擎,为数组提供更好的压缩,节省参数空间:
# Python 2import cPickle as pickleimport numpyprint len(pickle.dumps(numpy.random.normal(size=[1000, 1000])))# result: 23691675# Python 3import pickleimport numpylen(pickle.dumps(numpy.random.normal(size=[1000, 1000])))# result: 8000162
这个小的改进节省了3倍的空间,而且运行阶段速度更快。实际上,如果不关心速度的话,类似的压缩性能也可以通过设置参数 protocol=2 来实现,但是用户经常会忽略这个选项或者�...
文章浏览阅读1.2k次。其实,在真正的项目实战当中如果仅仅是使用硬盘缓存的话,程序是有明显短板的。而如果只使用内存缓存的话,程序当然也会有很大的缺陷。因此,一个优秀的程序必然会将内存缓存和硬盘缓存结合到一起使用,那么本篇文章我们就来看一看,如何才能将LruCache和DiskLruCache完美结合到一起。在 Android照片墙应用实现,再多的图片也不怕崩溃 这篇文章当中,我编写了一个照片墙的应用程序,但当时只_lrucache和disklrucached的照片墙
文章浏览阅读2.8k次,点赞3次,收藏8次。html:<div id="industrySectorScroll" :style="{ height: screenHeight + 'px' }"></div>js: export default { name: "industrySectorScroll", data() { return { screenWeight: 0, // 屏幕宽度 screenHeight: 0, // 屏幕高度 _vue给div赋值高度
文章浏览阅读2.6w次,点赞17次,收藏49次。简单的说就是两种不同的语言.但是它们之间既有联系又有区别_java和c的区别
文章浏览阅读4.1k次。Springboot整合swagger2时后,访问http://localhost:8080/swagger-ui.html时出现空白页如下我的swagger2版本为2.7.0。Swagger2的maven版本为2.7.0<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <versio_配置swagger2 解决访问/swagger-ui.html页面空白
文章浏览阅读2.2k次。--- a/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java+++ b/vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/sy..._android 开机后首次状态栏下拉偏移
文章浏览阅读1w次。错误情况项目用 maven 打好 war 包后放到 tomcat 下,启动 tomcat,出现以下错误3-Nov-2017 12:21:44.346 严重 [localhost-startStop-1] org.apache.catalina.core.ContainerBase.addChildInternal ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start compone_error in opening zip file
文章浏览阅读4.1k次。最近试用libreCAD,出现了一个小问题。用libreCAD绘制一幅图纸,保存为test.dxf。操作系统为win10, libreCAD的安装文件是:LibreCAD-Installer-2.2.0-rc1.exe过了两天,将libreCAD的界面语言切换成简体中文,再次打开test.dxf时,发现原本显示的文本内容都变成了一个矩形的空白方框。尝试将界面换回英文还是无法解决问题。设置文..._libre cad字体设置
文章浏览阅读554次。HDU一百题刷题笔记题号2003如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入题号开始刷杭电2000到2100一百题。比较基础。2003求绝对值 ,fabs表示求浮点数,abs返回整..._hdu100题
文章浏览阅读192次。#e1.3 Fibonacci_Sequence#coding = utf8"""书上正常内容"""a,b=0,1while a<1000: print(a,end='、') a,b=b,a+bprint()"""改进版,最后输出句号"""a,b=0,1print(a,end='')while b<1000: print('、'+str(b...
文章浏览阅读1.9k次,点赞6次,收藏9次。官网共11个表– 下载地址:http://www.quartz-scheduler.org/downloads/注意:创建,删除表要按顺序,涉计到外键约束drop table if exists qrtz_fired_triggers; -- 1 保存已经触发的触发器状态信息drop table if exists qrtz_paused_trigger_grps; -- 2 存放暂停掉的触发器表表drop table if exists qrtz_scheduler_state; _quartz 几张表quartz state
文章浏览阅读1.1k次。错误情形:错误原因:未知解决方法:去官网下载最新的jar包_idea导入mysql依赖标红
文章浏览阅读812次。原文地址:https://www.xuebuyuan.com/1722272.html一、基本概念一个视频图像可编码成一个或更多个条带,每个条带包含整数个宏块(MB),即每个条带至少一个MB,最多时每个条带包含整个图像的宏块。总之,一幅图像中每个条带的宏块数不一定固定。设条带的目的是为了限制误码的扩散和传输,应使编码条带相互间是独立的。某个条带的预测不能以其它条带中的宏块为参考图像,这样某一条带中的预测误差才不会传播到其它条带中去。Slice的类型如表1所示表1 Slice的类型说明_slice type