首页 >>  正文

python中两个小于什么意思

来源:baiyundou.net   日期:2024-09-21

丰色 发自 凹非寺

量子位 | 公众号 QbitAI

众所周知,Python的简单和易读性是靠牺牲性能为代价的——

尤其是在计算密集的情况下,比如多重for循环。

不过现在,大佬胡渊鸣说了:

只需import 一个叫做“Taichi”的库,就可以把代码速度提升100倍

不信?

来看三个例子。

计算素数的个数,速度x120

第一个例子非常非常简单,求所有小于给定正整数N的素数。

标准答案如下:

我们将上面的代码保存,运行。

当N为100万时,需要2.235s得到结果:

现在,我们开始施魔法。

不用更改任何函数体,import“taichi”库,然后再加两个装饰器:

Bingo!同样的结果只要0.363s,快了将近6倍。

如果N=1000万,则只要0.8s;要知道,不加它可是55s,一下子又快了70倍

不止如此,我们还可以在ti.init()中加个参数变为ti.init(arch=ti.gpu) ,让taich在GPU上进行计算。

那么此时,计算所有小于1000万的素数就只耗时0.45s了,与原来的Python代码相比速度就提高了120倍

厉不厉害?

什么?你觉得这个例子太简单了,说服力不够?我们再来看一个稍微复杂一点的。

动态规划,速度x500

动态规划不用多说,作为一种优化算法,通过动态存储中间计算结果来减少计算时间。

我们以经典教材《算法导论》中的经典动态规划案例“最长公共子序列问题(LCS)”为例。

比如对于序列a = [0, 1, 0, 2, 4, 3, 1, 2, 1]和序列b = [4, 0, 1, 4, 5, 3, 1, 2],它们的LCS就是:

LCS(a, b) = [0, 1, 4, 3, 1, 2]。

用动态规划的思路计算LCS,就是先求解序列a的前i个元素和序列b的前j个元素的最长公共子序列的长度,然后逐步增加i或j的值,重复过程,得到结果。

我们用f[i, j]来指代这个子序列的长度,即LCS((prefix(a, i), prefix(b, j)。其中prefix(a, i) 表示序列a的前i个元素,即a[0], a[1], …, a[i - 1],得到如下递归关系:

完整代码如下:

现在,我们用Taichi来加速:

结果如下:

胡渊鸣电脑上的程序最快做到了0.9秒内完成,而换成用NumPy来实现,则需要476秒,差异达到了超500倍!

最后,我们再来一个不一样的例子。

反应 - 扩散方程,效果惊人

自然界中,总有一些动物身上长着一些看起来无序但实则并非完全随机的花纹。

图灵机的发明者艾伦·图灵是第一个提出模型来描述这种现象的人。

在该模型中,两种化学物质(U和V)来模拟图案的生成。这两者之间的关系类似于猎物和捕食者,它们自行移动并有交互:

  1. 最初,U和V随机分布在一个域上;
  2. 在每个时间步,它们逐渐扩散到邻近空间;
  3. 当U和V相遇时,一部分U被V吞噬。因此,V的浓度增加;
  4. 为了避免U被V根除,我们在每个时间步添加一定百分比 (f) 的U并删除一定百分比 (k) 的V。

上面这个过程被概述为“反应-扩散方程”:

其中有四个关键参数:Du(U的扩散速度),Dv(V的扩散速度),f(feed的缩写,控制U的加入)和k(kill的缩写,控制V的去除)

如果Taichi中实现这个方程,首先创建网格来表示域,用vec2表示每个网格中U, V的浓度值。

拉普拉斯算子数值的计算需要访问相邻网格。为了避免在同一循环中更新和读取数据,我们应该创建两个形状相同的网格W×H×2。

每次从一个网格访问数据时,我们将更新的数据写入另一个网格,然后切换下一个网格。那么数据结构设计就是这样:

一开始,我们将U在网格中的浓度设置为 1,并将V放置在50个随机选择的位置:

那么实际计算就可以用不到10行代码完成:

","force_purephv":"0","gnid":"937e299d4c2c2a176","img_data":[{"flag":2,"img":[{"desc":"","height":"920","title":"","url":"https://p0.ssl.img.360kuai.com/t01e23794c94540b7d3.jpg","width":"920"},{"desc":"","height":"765","title":"","url":"https://p0.ssl.img.360kuai.com/t0144fb37a5bf3f53de.jpg","width":"1080"},{"desc":"","height":"227","title":"","url":"https://p0.ssl.img.360kuai.com/t0150b2fef7620e3dbc.jpg","width":"1080"},{"desc":"","height":"839","title":"","url":"https://p0.ssl.img.360kuai.com/t016b17cfbc73cc0857.jpg","width":"1080"},{"desc":"","height":"218","title":"","url":"https://p0.ssl.img.360kuai.com/t0179edf8404f9ae37d.jpg","width":"1080"},{"desc":"","height":"106","title":"","url":"https://p0.ssl.img.360kuai.com/t01e32851aaad11b65f.jpg","width":"1080"},{"desc":"","height":"179","title":"","url":"https://p0.ssl.img.360kuai.com/t01bec382de36100f5c.jpg","width":"1080"},{"desc":"","height":"1048","title":"","url":"https://p0.ssl.img.360kuai.com/t01d29f206b72759e5c.jpg","width":"952"},{"desc":"","height":"220","title":"","url":"https://p0.ssl.img.360kuai.com/t013e42423d8b222dd8.jpg","width":"1080"},{"desc":"","height":"200","title":"","url":"https://p0.ssl.img.360kuai.com/t01d2b2fb1751d67f82.jpg","width":"1080"},{"desc":"","height":"290","title":"","url":"https://p0.ssl.img.360kuai.com/t01a6e79e099eafb7c4.jpg","width":"732"},{"desc":"","height":"103","title":"","url":"https://p0.ssl.img.360kuai.com/t0120a647a3f436ce6b.jpg","width":"1080"},{"desc":"","height":"321","title":"","url":"https://p0.ssl.img.360kuai.com/t01758422991b7876fd.jpg","width":"1080"}]}],"original":0,"pat":"art_src_3,fts0,sts0","powerby":"cache","pub_time":1662700080000,"pure":"","rawurl":"http://zm.news.so.com/ff7cacee7feffebd5b82b9dcf2d60187","redirect":0,"rptid":"aec5ec457dee7f65","s":"t","src":"量子位","tag":[],"title":"胡渊鸣:import一个“太极”库,让Python代码提速100倍

訾夜非1645请问python中val[0: - 1]是什么意思? -
庾要颖18095221403 ______ val[0:-1]是python特有的切片操作,也叫切割操作,这里的下标0表示左起第一个元素, -1表示倒数最后一个元素. 取一个list或tuple的部分元素是非常常见的操作.比如,一个list如下: “L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']” 取前3个元素...

訾夜非1645Python 正则表达式 r"(?<=<h1>).+?(?=<h1>)"中?<=和?=是什么意思 -
庾要颖18095221403 ______ (?<=<h1>) 表示在此后的正则中,前面要匹配<h1> (?=<h1>) 表示在此前的正则中,后面要匹配<h1> 这两个表达式表示的是条件,不是实际匹配正则的一部分

訾夜非1645Python:编写一个程序,输出三个数中两个较大值的平均值. -
庾要颖18095221403 ______ a=int(input()) s=str(a) if len(s)>3: print('大于三位') else: x=a//100 #百位数 y=(a//10)%10 #十 z=(a%100)%10 # 个 l=list((x,y,z)) #转化为数组 l.sort() #数据排序 coutn=sum(l[1:])/2 #后两位求合取均值 print(coutn)

訾夜非1645python中对%转义为何是%%,%和\转义有什么区别吗 -
庾要颖18095221403 ______ 区别是因为python解释器会把7交给第一个%号后面的d,而两个%%号会被解析成一个%号. 'growth rate: %d %%' % 7 这行代码你可以运行一下,转义第二个%号应该是\. 常见电脑故障 开机无显示 电脑开机无显示,首先要检查的就是是BIOS.主板的BIOS中储存着重要的硬件数据,同时BIOS也是主板中比较脆弱的部分,极易受到破坏,一旦受损就会导致系统无法运行,出现此类故障一般是因为主板BIOS被CIH病毒破坏造成(当然也不排除主板本身故障导致系统无法运行). 一般BIOS被病毒破坏后硬盘里的数据将全部丢失,所以可以通过检测硬盘数据是否完好来判断BIOS是否被破坏.

訾夜非1645在Python中输入两个三位数,编程将其拼成一个六位数,如123与456,得到123456 -
庾要颖18095221403 ______ teststr = "" for n in range(1,3): teststr += input('输入第'+str(n)+'个数>>') print(teststr) 或 s=int(input('')) q=int(s/100) b=int(s/10)-q*10 g=s-100*q-b*10 s=q+b+g print(s) 扩展资料: Python的表达式写法与C/C++类似.只是在某些写法有所...

訾夜非1645下面python中的不同的下划线代表什么意思呢 -
庾要颖18095221403 ______ 下划线一般有两种情况: 1、两边都有两个下划线的情况:这一般是指内建预定义属性,这种内建预定义属性. 2、中间一根下划线:这个命名中两个单词的分割线,这个以前OO编程中单词首字母大写差不多一个作用,只不过一般python的模块函数编程会用下划线分割这种方式.

訾夜非1645python 中 方法def total(*numbers, **keywords): 参数列表中1个*和2个*分别代表什么意识 -
庾要颖18095221403 ______ 用在函数定义里,numbers捕获了所有的位置参数(非keyword参数),keywords捕获了所有的keywords参数.例子:>>> def f(*args, **kwargs):. . . print type(args), args. . . print type(kwargs), kwargs. . . >>> f(1,2, a=3)<type 'tuple'> (1, 2)<type 'dict'...

訾夜非1645在数学中,两个小于号在一起是什么意思.例如:丨△x丨<<1,求解? -
庾要颖18095221403 ______[答案] 就是说 远远的小于 丨△x丨<<1 丨△x丨远远的小于1

訾夜非1645python中 -
庾要颖18095221403 ______ py中字符串的比较默认是通过ASCII来比较,通过重载可以实现其它的比较策略.而第一个(3,2)只是在2x版本里支持,比较的结果无意义,并不是数字多大都小于字符,而是在比较之前首先比较类型,标识数字类型小于字符串类型,可以通过一个测试来看看比较的顺序.a = [ { } ,( ) ,[ ] ,1 ,'ds' ,object( ) ,object ] print( sorted( a ) ) 得出的结果是 [1, {}, [], , 'ds', (), ] 这种类型的比较没有任何的意义,所以在3x版本里默认将不允许这种比较,只会得到TypeError.

(编辑:自媒体)
关于我们 | 客户服务 | 服务条款 | 联系我们 | 免责声明 | 网站地图 @ 白云都 2024