当前位置: 首页 > 编程日记 > 正文

Python编写循环的两个建议 | 鹅厂实战

640?wx_fmt=jpeg


作者 | piglei(腾讯高级工程师)

转载自腾讯技术工程知乎专栏


循环是一种常用的程序控制结构。我们常说,机器相比人类的最大优点之一,就是机器可以不眠不休的重复做某件事情,但人却不行。而“循环”,则是实现让机器不断重复工作的关键概念。


在循环语法方面,Python 表现的即传统又不传统。它虽然抛弃了常见的 for(init;condition;incrment) 三段式结构,但还是选择了 for 和 while 这两个经典的关键字来表达循环。绝大多数情况下,我们的循环需求都可以用 for<item>in<iterable> 来满足, while<condition> 相比之下用的则更少些。


虽然循环的语法很简单,但是要写好它确并不容易。在这篇文章里,我们将探讨什么是“地道”的循环代码,以及如何编写它们。


什么是“地道”的循环?


“地道”这个词,通常被用来形容某人做某件事情时,非常符合当地传统,做的非常好。打个比方,你去参加一个朋友聚会,同桌的有一位广东人,对方一开口,句句都是标准京腔、完美儿化音。那你可以对她说:“您的北京话说的真地道”。


既然“地道”这个词形容的经常是口音、做菜的口味这类实实在在的东西,那“地道”的循环代码又是什么意思呢?让我拿一个经典的例子来解释一下。


如果你去问一位刚学习 Python 一个月的人:“如何在遍历一个列表的同时获取当前下标?”。他可能会交出这样的代码:



上面的循环虽然没错,但它确一点都不“地道”。一个拥有三年 Python 开发经验的人会说,代码应该这么写:


for i, name in enumerate(names):
    print(i, name)


enumerate() 是 Python 的一个内置函数,它接收一个“可迭代”对象作为参数,然后返回一个不断生成 (当前下标,当前元素) 的新可迭代对象。这个场景使用它最适合不过。


所以,在上面的例子里,我们会认为第二段循环代码比第一段更“地道”。

因为它用更直观的代码,更聪明的完成了工作。


enumerate() 所代表的编程思路


不过,判断某段循环代码是否地道,并不仅仅是以知道或不知道某个内置方法作为标准。我们可以从上面的例子挖掘出更深层的东西。


如你所见,Python 的 for 循环只有 for<item>in<iterable> 这一种结构,而结构里的前半部分 - 赋值给 item- 没有太多花样可玩。所以后半部分的可迭代对象是我们唯一能够大做文章的东西。而以 enumerate() 函数为代表的“修饰函数”,刚好提供了一种思路:通过修饰可迭代对象来优化循环本身。


这就引出了我的第一个建议。


建议1:使用函数修饰被迭代对象来优化循环


使用修饰函数处理可迭代对象,可以在各种方面影响循环代码。而要找到合适的例子来演示这个方法,并不用去太远,内置模块 itertools 就是一个绝佳的例子。


简单来说,itertools 是一个包含很多面向可迭代对象的工具函数集。我在之前的系列文章《容器的门道》里提到过它。


如果要学习 itertools,那么 Python 官方文档 是你的首选,里面有非常详细的模块相关资料。但在这篇文章里,侧重点将和官方文档稍有不同。我会通过一些常见的代码场景,来详细解释它是如何改善循环代码的。


1. 使用 product 扁平化多层嵌套循环


虽然我们都知道“扁平的代码比嵌套的好”。但有时针对某类需求,似乎一定得写多层嵌套循环才行。比如下面这段:


def find_twelve(num_list1, num_list2, num_list3):
    """从 3 个数字列表中,寻找是否存在和为 12 的 3 个数
    """

    for num1 in num_list1:
        for num2 in num_list2:
            for num3 in num_list3:
                if num1 + num2 + num3 == 12:
                    return num1, num2, num3


对于这种需要嵌套遍历多个对象的多层循环代码,我们可以使用 product() 函数来优化它。product() 可以接收多个可迭代对象,然后根据它们的笛卡尔积不断生成结果。


from itertools import product

def find_twelve_v2(num_list1, num_list2, num_list3):
    for num1, num2, num3 in product(num_list1, num_list2, num_list3):
        if num1 + num2 + num3 == 12:
            return num1, num2, num3


相比之前的代码,使用 product() 的函数只用了一层 for 循环就完成了任务,代码变得更精炼了。


2. 使用 islice 实现循环内隔行处理


有一份包含 Reddit 帖子标题的外部数据文件,里面的内容格式是这样的:


python-guide: Python best practices guidebook, written for humans.
---
Python 2 Death Clock
---
Run any Python Script with an Alexa Voice Command
---
<... ...>


可能是为了美观,在这份文件里的每两个标题之间,都有一个 "---" 分隔符。现在,我们需要获取文件里所有的标题列表,所以在遍历文件内容的过程中,必须跳过这些无意义的分隔符。


参考之前对 enumerate() 函数的了解,我们可以通过在循环内加一段基于当前循环序号的 if 判断来做到这一点:


def parse_titles(filename):
    """从隔行数据文件中读取 reddit 主题名称
    """

    with open(filename, 'r'as fp:
        for i, line in enumerate(fp):
            # 跳过无意义的 '---' 分隔符
            if i % 2 == 0:
                yield line.strip()


但对于这类在循环内进行隔行处理的需求来说,如果使用 itertools 里的 islice() 函数修饰被循环对象,可以让循环体代码变得更简单直接。


islice(seq,start,end,step) 函数和数组切片操作( list[start:stop:step] )有着几乎一模一样的参数。如果需要在循环内部进行隔行处理的话,只要设置第三个递进步长参数 step 值为 2 即可(默认为 1)。


from itertools import islice

def parse_titles_v2(filename):
    with open(filename, 'r'as fp:
        # 设置 step=2,跳过无意义的 '---' 分隔符
        for line in islice(fp, 0None2):
            yield line.strip()


3. 使用 takewhile 替代 break 语句


有时,我们需要在每次循环开始时,判断循环是否需要提前结束。比如下面这样:


for user in users:
    # 当第一个不合格的用户出现后,不再进行后面的处理
    if not is_qualified(user):
        break

    # 进行处理 ... ...


对于这类需要提前中断的循环,我们可以使用 takewhile() 函数来简化它。takewhile(predicate,iterable)会在迭代 iterable 的过程中不断使用当前对象作为参数调用 predicate 函数并测试返回结果,如果函数返回值为真,则生成当前对象,循环继续。否则立即中断当前循环。


使用 takewhile 的代码样例:


from itertools import takewhile

for user in takewhile(is_qualified, users):
    # 进行处理 ... ...


itertools 里面还有一些其他有意思的工具函数,他们都可以用来和循环搭配使用,比如使用 chain 函数扁平化双层嵌套循环、使用 zip_longest 函数一次同时循环多个对象等等。


篇幅有限,我在这里不再一一介绍。如果有兴趣,可以自行去官方文档详细了解。


4. 使用生成器编写自己的修饰函数


除了 itertools 提供的那些函数外,我们还可以非常方便的使用生成器来定义自己的循环修饰函数。


让我们拿一个简单的函数举例:


def sum_even_only(numbers):
    """对 numbers 里面所有的偶数求和"""
    result = 0
    for num in numbers:
        if num % 2 == 0:
            result += num
    return result


在上面的函数里,循环体内为了过滤掉所有奇数,引入了一条额外的 if 判断语句。如果要简化循环体内容,我们可以定义一个生成器函数来专门进行偶数过滤:


def even_only(numbers):
    for num in numbers:
        if num % 2 == 0:
            yield num

def sum_even_only_v2(numbers):
    """对 numbers 里面所有的偶数求和"""
    result = 0
    for num in even_only(numbers):
        result += num
    return result


将 numbers 变量使用 even_only 函数装饰后, sum_even_only_v2 函数内部便不用继续关注“偶数过滤”逻辑了,只需要简单完成求和即可。


Hint:当然,上面的这个函数其实并不实用。在现实世界里,这种简单需求最适合直接用生成器/列表表达式搞定:sum(numfornuminnumbersifnum%2==0)


建议2:按职责拆解循环体内复杂代码块


我一直觉得循环是一个比较神奇的东西,每当你写下一个新的循环代码块,就好像开辟了一片黑魔法阵,阵内的所有内容都会开始无休止的重复执行。


但我同时发现,这片黑魔法阵除了能带来好处,它还会引诱你不断往阵内塞入越来越多的代码,包括过滤掉无效元素、预处理数据、打印日志等等。甚至一些原本不属于同一抽象的内容,也会被塞入到同一片黑魔法阵内。


你可能会觉得这一切理所当然,我们就是迫切需要阵内的魔法效果。如果不把这一大堆逻辑塞满到循环体内,还能把它们放哪去呢?


让我们来看看下面这个业务场景。在网站中,有一个每 30 天执行一次的周期脚本,它的任务是是查询过去 30 天内,在每周末特定时间段登录过的用户,然后为其发送奖励积分。


代码如下:


import time
import datetime

def award_active_users_in_last_30days():
    """获取所有在过去 30 天周末晚上 8 点到 10 点登录过的用户,为其发送奖励积分
    """

    days = 30
    for days_delta in range(days):
        dt = datetime.date.today() - datetime.timedelta(days=days_delta)
        # 5: Saturday, 6: Sunday
        if dt.weekday() not in (56):
            continue

        time_start = datetime.datetime(dt.year, dt.month, dt.day, 200)
        time_end = datetime.datetime(dt.year, dt.month, dt.day, 230)

        # 转换为 unix 时间戳,之后的 ORM 查询需要
        ts_start = time.mktime(time_start.timetuple())
        ts_end = time.mktime(time_end.timetuple())

        # 查询用户并挨个发送 1000 奖励积分
        for record in LoginRecord.filter_by_range(ts_start, ts_end):
            # 这里可以添加复杂逻辑
            send_awarding_points(record.user_id, 1000


上面这个函数主要由两层循环构成。外层循环的职责,主要是获取过去 30 天内符合要求的时间,并将其转换为 UNIX 时间戳。之后由内层循环使用这两个时间戳进行积分发送。


如之前所说,外层循环所开辟的黑魔法阵内被塞的满满当当。但通过观察后,我们可以发现整个循环体其实是由两个完全无关的任务构成的:“挑选日期与准备时间戳” 以及 “发送奖励积分”。


复杂循环体如何应对新需求


这样的代码有什么坏处呢?让我来告诉你。


某日,产品找过来说,有一些用户周末半夜不睡觉,还在刷我们的网站,我们得给他们发通知让他们以后早点睡觉。于是新需求出现了:“给过去 30 天内在周末凌晨 3 点到 5 点登录过的用户发送一条通知”


新问题也随之而来。敏锐如你,肯定一眼可以发现,这个新需求在用户筛选部分的要求,和之前的需求非常非常相似。但是,如果你再打开之前那团循环体看看,你会发现代码根本没法复用,因为在循环内部,不同的逻辑完全被耦合在一起了。☹️


在计算机的世界里,我们经常用“耦合”这个词来表示事物之间的关联关系。上面的例子中,“挑选时间”和“发送积分”这两件事情身处同一个循环体内,建立了非常强的耦合关系。


为了更好的进行代码复用,我们需要把函数里的“挑选时间”部分从循环体中解耦出来。而我们的老朋友,“生成器函数”是进行这项工作的不二之选。


使用生成器函数解耦循环体


要把 “挑选时间” 部分从循环内解耦出来,我们需要定义新的生成器函数 gen_weekend_ts_ranges(),专门用来生成需要的 UNIX 时间戳:


def gen_weekend_ts_ranges(days_ago, hour_start, hour_end):
    """生成过去一段时间内周六日特定时间段范围,并以 UNIX 时间戳返回
    """

    for days_delta in range(days_ago):
        dt = datetime.date.today() - datetime.timedelta(days=days_delta)
        # 5: Saturday, 6: Sunday
        if dt.weekday() not in (56):
            continue

        time_start = datetime.datetime(dt.year, dt.month, dt.day, hour_start, 0)
        time_end = datetime.datetime(dt.year, dt.month, dt.day, hour_end, 0)

        # 转换为 unix 时间戳,之后的 ORM 查询需要
        ts_start = time.mktime(time_start.timetuple())
        ts_end = time.mktime(time_end.timetuple())
        yield ts_start, ts_end


有了这个生成器函数后,旧需求“发送奖励积分”和新需求“发送通知”,就都可以在循环体内复用它来完成任务了:


def award_active_users_in_last_30days_v2():
    """发送奖励积分"""
    for ts_start, ts_end in gen_weekend_ts_ranges(30, hour_start=20, hour_end=23):
        for record in LoginRecord.filter_by_range(ts_start, ts_end):
            send_awarding_points(record.user_id, 1000)

def notify_nonsleep_users_in_last_30days():
    """发送通知"""
    for ts_start, ts_end in gen_weekend_ts_range(30, hour_start=3, hour_end=6):
        for record in LoginRecord.filter_by_range(ts_start, ts_end):
            notify_user(record.user_id, 'You should sleep more')


总结


在这篇文章里,我们首先简单解释了“地道”循环代码的定义。然后提出了第一个建议:使用修饰函数来改善循环。之后我虚拟了一个业务场景,描述了按职责拆解循环内代码的重要性。


一些要点总结:


  • 使用函数修饰被循环对象本身,可以改善循环体内的代码

  • itertools 里面有很多工具函数都可以用来改善循环

  • 使用生成器函数可以轻松定义自己的修饰函数

  • 循环内部,是一个极易发生“代码膨胀”的场地

  • 请使用生成器函数将循环内不同职责的代码块解耦出来,获得更好的灵活性


看完文章的你,有没有什么想吐槽的?请留言或者在 项目 Github Issues 告诉我吧。


附录


  • 题图来源: Photo by Lai man nung on Unsplash

  • 更多系列文章地址:https://github.com/piglei/one-python-craftsman


(*本文为 AI科技大本营转载文章,转载请联系原作者)


精彩推荐



640?wx_fmt=png


6月29-30日,2019以太坊技术及应用大会 特邀以太坊创始人V神与以太坊基金会核心成员,以及海内外知名专家齐聚北京,聚焦前沿技术,把握时代机遇,深耕行业应用,共话以太坊2.0新生态。


扫码或点击阅读原文,既享优惠购票!


640?wx_fmt=jpeg


推荐阅读

  • Bert时代的创新:Bert在NLP各领域的应用进展 | 技术头条

  • 免费GPU哪家强?谷歌Kaggle vs. Colab

  • 高能!8段代码演示Numpy数据运算的神操作

  • Python编写循环的两个建议 | 鹅厂实战

  • Lambda 表达式有何用处?

  • 9年前他用1万个比特币买了两个披萨, 9年后他把当年的代码卖给了苹果,成为了 GPU 挖矿之父

  • TIOBE 6月编程语言排行榜:Python 势不可挡,或在四年之内超越Java、C

  • 漫威金刚狼男主弃影炒币了?



640?wx_fmt=png你点的每个“在看”,我都认真当成了喜欢

相关文章:

作为JavaScript开发人员,这些必备的VS Code插件你都用过吗

本文翻译自&#xff1a;https://www.sitepoint.com/vs-code-extensions-java-developers/转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。如今&#xff0c;Visual Studio Code无疑是最流行的轻量级…

matlab常遇小问题汇总

1、如何注释掉多行&#xff1a; 同时注释掉多行&#xff0c;有2种方法可行&#xff1a; (1)、选中所有要注释的行&#xff0c;按快捷键"Ctrl R" 或者 选择工具菜单"Text --> Comment"; 如果释放所有要注释的行&#xff0c;则按快捷键"Ctrl T&qu…

《几何与代数导引》习题1.35.4

求直线之间的距离$l_1:\frac{x1}{-1}\frac{y-1}{3}\frac{z5}{2}$.$l_2:\frac{x}{3}\frac{y-6}{-9}\frac{z5}{-6}$.解&#xff1a;点$q(-1,1,-5)$在直线$l_1$上&#xff0c;点$p(0,6,-5)$在直线$l_2$上.$\vec{pq}(-1,-5,0)$.直线$l_1$的方向向量为$(-1,3,2)$,直线$l_2$的方向向量…

深度学习难,这本书让你轻松学深度学习

深度学习在短短几年之内便让世界大吃一惊。它非常有力地推动了计算机视觉、自然语言处理、自动语音识别、强化学习和统计建模等多个领域的快速发展。随着这些领域的不断进步&#xff0c;人们现在可以制造自动驾驶的汽车&#xff0c;基于短信、邮件甚至电话的自动回复系统&#…

matlab中用于小数取整的函数的用法

matlab中小数取整的函数大约有四个&#xff1a;floor、ceil、round、fix 若 A [-2.0, -1.9, -1.55, -1.45, -1.1, 1.0, 1.1, 1.45, 1.55, 1.9, 2.0]; floor:朝负无穷方向靠近最近的整数&#xff1b; floor(A) ans -2 -2 -2 -2 -2 1 1 1 1 …

SQLServer之删除约束

使用SSMS数据库管理工具删除约束 1、连接数据库&#xff0c;选择数据表-》展开键或者约束-》选择要删除的约束-》右键点击-》选择删除。 2、在删除对象弹出框中-》点击确定。 3、刷新表-》展开键或者约束-》查看结果。 使用T-SQL脚本删除约束 语法&#xff1a; --声明数据库使用…

新建silverlight项目提示未将对象设置到实例解决方案

1.打开 visual studio 命令提示 输入一下命令 2.devenv /resetskippkgs 这条命令会启动visual stuio 关闭visual studio然后输入下面的命令3.devenv /setup

毕业十年后,我忍不住出了一份程序员的高考试卷

作者 | 程序员小吴转载自公众号五分钟学算法&#xff08;ID: CXYxiaowu&#xff09;一、选择题&#xff08;共计 50 分&#xff09;1、在下列四种排序算法&#xff0c;只有&#xff08; &#xff09;是一种不稳定排序A、冒泡排序B、选择排序C、插入排序D、归并排序2、一个数组&…

查看matlab中函数源代码的方法

有几种方法可以实现查看matlab里自带函数的源代码&#xff1a; 在命令窗口中输入&#xff1a; (1)、type 函数名(如 type rgb2gray 或者 type rgb2gray.m):即可在命令窗口中显示此函数的源代码&#xff1b; (2)、open 函数名(如 open rgb2gray 或者 open rgb2gray.m):即可打开…

Watir-webdriver处理table

最近大脸猫同学给了我一个popup的demo&#xff0c;让我试着定位弹出窗口中的按钮元素。在研究过程中&#xff0c;发现webdriver与watir代码有区别&#xff0c;一度让我很郁闷&#xff0c;在网上也找不到相应的解决方案&#xff0c;刚才code运行成功&#xff0c;在这记一笔&…

PyTorch Hub发布获Yann LeCun强推!一行代码调用经典模型

作者 | Team PyTorch译者 | Monanfei责编 | 夕颜出品 | AI科技大本营&#xff08;ID: rgznai100&#xff09;导读&#xff1a;6月11日&#xff0c;Facebook PyTorch 团队推出了全新 API PyTorch Hub&#xff0c;提供模型的基本构建模块&#xff0c;用于提高机器学习研究的模型复…

【会议纪要】非洲新经济-线下沙龙分享

沙龙 主题&#xff1a; 《解开非洲新经济神秘面纱》 时间&#xff1a; 2018年09月08日 14&#xff1a;00 ~ 15&#xff1a;00 地点&#xff1a; 杭州丰潭路 UXCoffee 背景&#xff1a; 随着中非合作峰会召开&#xff0c;非洲发展潜力越来越受到关注。。。许多人眼中的非洲是贫穷…

图像处理和图像识别中常用的matlab函数

下面仅给出函数的大概意思&#xff0c;详细用法见&#xff1a; help 函数名 或 matlab help 1、imread&#xff1a;read image from graphics file&#xff1b; 2、imshow&#xff1a;display image in Handle Graphics figure&#xff1b; 3、imwrite&#xff1a;write image…

Powershell管理Active Directory 复制和拓扑

Powershell管理Active Directory 复制和拓扑 Active Directory 的 Windows PowerShell (AD) 支持复制和拓扑管理。它包含了管理复制、站点、域和林、域控制器和分区的功能。过去的管理工具&#xff08;如 AD 站点和服务管理单元与 repadmin.exe&#xff09;的用户将发现如今也可…

实战 | 如何用最快的速度学会Dlib人脸识别开发?

作者 | 小宋是呢来源 | 转载自小宋是呢项目GitHub地址&#xff1a;https://github.com/xiaosongshine/dlib_face_recognition1.背景介绍Dlib是一个深度学习开源工具&#xff0c;基于C开发&#xff0c;也支持Python开发接口&#xff0c;功能类似于TensorFlow与PyTorch。但是由于…

matlab内存管理

转自&#xff1a;http://my.donews.com/deng/2006/09/24/vijgqxehmkxiruywdauvxyiafogtskeymhyw/ 用 Matlab 进行大规模科学计算或仿真时&#xff0c;内存是一个需要时常注意的问题。当你写的 Matlab 程序跳出“Out of Memory” 时&#xff0c;以下几点措施是需要优先考虑的解决…

Koa2和Redux中间件源码研究

一、Koa2中间件源码分析 在Koa2中&#xff0c;中间件被存放在一个数组中。 使用koa中&#xff0c;最常见的就是app.use(fn)&#xff0c;use函数部分源码如下所示。首先中间件必须是个函数。若是generator函数&#xff0c;则需要进行转化。最后把该中间件推入middelaware数组中。…

matlab内存管理(二)

转自&#xff1a;http://hi.baidu.com/bi%CB%AB%C9%FA%BB%A8/blog/item/5ab86c38ac2f45e715cecbab.html 1&#xff0c;确保内存的连续性Matlab 中数组必须占用连续分配的内存段当无法为新建的数组分配连续的内存段的时候Out of Memory 就会出现由于反复分配和释放数组会使可用的…

校招经验分享—高考结束!校招还会远么~~

作者 | 石晓文来源 | 转载自小小挖掘机&#xff08;ID: wAIsjwj&#xff09;今天是6.11&#xff0c;高考已经结束了&#xff0c;那大考-校招还会远么&#xff1f;我们先来看一下去年的校招时间表&#xff1a;互联网大厂校招一般7月就开始了&#xff0c;也就是说&#xff01;如果…

数据科学究竟是什么?

数据科学是一门将数据变得有用的学科。它包含三个重要概念&#xff1a; 统计机器学习数据挖掘/分析数据科学的定义 如果你回顾一下数据科学这个术语的[早期历史]()&#xff0c;会发现有两个主题密切相连&#xff1a; 大数据意味着计算机的使用频率增加。统计学家很难将纸张上所…

SQL with NUll处理,Join系列,between,in对比exists以及少量题目

2019独角兽企业重金招聘Python工程师标准>>> 1.一些题目: 选择在每一组B值相同的数据中对应的a最大的记录的所有信息,(用于论坛每月排行榜) Selecta,b,c from tableta wherea(select max(a) from tabletb where tableb.b tableta.b ) 随机抽取出10条数据 Select to…

清华大学提出APDrawingGAN,人脸照片秒变艺术肖像画

作者 | 刘永进教授来源 | 转载自数据派THU&#xff08;ID:DatapiTHU&#xff09;清华大学提出APDrawingGAN&#xff0c;该项工作被CVPR 2019录取为oral paper。CVPR是计算机视觉和人工智能领域内的国际顶级会议&#xff0c;2019共收到投稿5160篇&#xff0c;录取1300篇&#xf…

图像处理和图像识别中常用的OpenCV函数

1. cvLoadImage&#xff1a;将图像文件加载至内存&#xff1b; 2. cvNamedWindow&#xff1a;在屏幕上创建一个窗口&#xff1b; 3. cvDestroyWindow&#xff1a;销毁显示图像文件的窗口&#xff1b; 4. cvDestroyAllWindows&#xff1a;销毁显示图像文件的所有窗口…

SQLServer之DEFAULT约束

原文:SQLServer之DEFAULT约束DEFAULT约束添加规则 1、若在表中定义了默认值约束&#xff0c;用户在插入新的数据行时&#xff0c;如果该行没有指定数据&#xff0c;那么系统将默认值赋给该列&#xff0c;如果我们不设置默认值&#xff0c;系统默认为NULL。 2、如果“默认值”字…

tmux/screen里面如何用鼠标滚轮来卷动窗口内容

tmux里面用鼠标滚轮来卷动窗口内容在 tmux里面&#xff0c;因为每个窗口(tmux window)的历史内容已经被tmux接管了&#xff0c;所以原来console/terminal提供的ShiftPgUp/PgDn所显示的内容并不是当前窗口的历史内容&#xff0c;所以要用C-b [ 进入copy-mode&#xff0c;然后才能…

图像空间变换--imtransform

转自&#xff1a;http://juyishaanxi.blog.163.com/blog/static/602733002010522105439617/(非原处)空间几何变换将(w,z)坐标系上的图像变换为(x,y)坐标系上的图像&#xff0c;可以表示为&#xff1a; (x,y) T{(w,z) 比如&#xff1a; (x,y) T{(w,z)} (w/2, z/2) 仿射变…

谷歌用1.2万个模型“推翻”现有无监督研究成果!斩获ICML 2019最佳论文

作者 | 夕颜、Just出品 | AI科技大本营(ID:rgznai100)6 月 11 日&#xff0c;在美国加州长滩举行的 ICML 公布了 2019 年最佳论文奖&#xff0c;来自苏黎世联邦理工大学、谷歌大脑等的团队和英国剑桥大学团队摘得最佳论文奖项&#xff0c;此外&#xff0c;大会还公布了 7 篇获最…

实战:掌握PyTorch图片分类的简明教程 | 附完整代码

作者 | 小宋是呢转载自CSDN博客1.引文深度学习的比赛中&#xff0c;图片分类是很常见的比赛&#xff0c;同时也是很难取得特别高名次的比赛&#xff0c;因为图片分类已经被大家研究的很透彻&#xff0c;一些开源的网络很容易取得高分。如果大家还掌握不了使用开源的网络进行训练…

python group()

正则表达式中&#xff0c;group&#xff08;&#xff09;用来提出分组截获的字符串&#xff0c;&#xff08;&#xff09;用来分组 import re a "123abc456" print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0) #123abc456,返回整体 print re.sea…

图像配准的方法

转自&#xff1a;http://blog.sina.com.cn/s/blog_4b9b714a0100d5k5.html 图像配准的方法 1 基于特征的图像配准 基于特征的图像配准首先提取图像信息的特征&#xff0c;然后以这些特征为模型进行配准。特征提取的结果是一含有特征的表和对图像的描述&#xff0c;每个特征由…