有Java基础的程序员,是如何看待Python这位少女的?
随着人工智能的火热,Python作为这块领域中的佼佼者,也得到了迅猛的发展。作为一门强类型的动态脚本语言,Python与JavaScript非常相似,无论是语法思维上还是可用的基础工具(内置API)上,对于写惯了JavaScript的我们来说,Python非常的友好,友好在哪呢?我们一起来看看吧。
由于我们都是有JavaScript基础了,所以学习Python的方式得做一些小改变,不需要去看文档学习API,那样其实蛮累的,毕竟脱离了生产的学习API,就犹如听着昏昏欲睡,毫无感情色彩的四六级听力,嚼着一段段生搬硬套硬凑生词的阅读理解,你很难真正的听懂、读懂它。(有幸在车站跟外国人交流过,他们说的话听起来真的很优美,很灵动,这跟一直是第一声的四六级完全不同,好吧,扯远了)
学Python,我的理解 —— 就像学JQuery,学会一个$(id class tag),理解它比原生JS对于DOM操作的简化就够了,其他的五花八门的API,你在生产环境下用上一遍,自然而然就会了。
这里我们也是一样,不学习它的API,我们用Python来解决问题,解着解着,你自然也就会了,而且可以让你的头发少掉那么几根。= =
我们遇到的第一个问题是 —— 抽奖。
用JavaScript写抽奖你肯定信手拈来,呼啦啦看着那个大转盘咕噜咕噜就是一顿猛操作。这里我们只取其中最重要的一部分,也就是摇出幸运者的逻辑。我们可以把它抽象成下面这样:
1、抽奖箱里的号码为员工号码,我们看成一个数组,假设这时候的员工号码为1~100号。
2、抽奖到的那位不能再继续参与抽奖。
3、假设我们要抽取若干位幸运者(比如5位幸运者)
这时候我们想:先建一个数组来装幸运者,接着随机一个从1-100号的数字,并且判定一下这个随机出来的数字是否在幸运者数组中,如果没有就加进去,有就重新随机。
我们先来看一下我们熟悉的JavaScript,基本上你可以发现有条不紊的按照我们的思路进行着。
const randomNums_0 = (a, b, n) => {
// 建一个数组 let res = []; // 生成 a~b 的随机号码 const createRandom = (a, b) => Math.floor(Math.random() * (b - a) + a); while(n) { let val = createRandom(a, b); if(res.indexOf(val) === -1) { // 如果这个随机的号码在幸运者的队列中不存在 res.push(val); // 则将这个号码添加进去 n --; // 这里的n是幸运者的人数,当队列中多了一个幸运者,n就减一 } // 否则重新生成随机数 } return res;
}
console.log(randomNums_0(1, 100, 5));
这时做过了一遍之后,再返回来看看Python版。(这里的Python是Python3.7,对于Python2的语法异同(语法不兼容其实不少,最常见的比如Python2的print 与Python3的 print()。这里就不说了,只说Python3。)
# 简单抽奖 —— 生成n个输入范围在a ~ b内的不同随机整数。 # 难度 # 函数接收3个数字,分别为a, b, n。 def _20191020(): # the first solution def randomNums_0 (a, b, n): res = [] while n: num = math.floor(random.random() * (b - a) + a) if num not in res: res.append(num) n -= 1 return res print(randomNums_0(1, 100, 5))
基本的套路其实一模一样,只不过稍微语法不同:
1、 JavaScript的函数定义是通过function,或者通过箭头表达式。而Python则是通过def。def其实就是定义的意思,define嘛。
// JavaScript
function fn () { ... }
const fn = argus => { ... }
Python
def fn ():
python的函数没有大括号包裹,而是通过":"来做判定。
2、 我们的判断数组是否包含某个成员,我们的初步思路就是判断它的索引是不是大于-1,这里Python做得更好,它直接就是:
if num not in res:
你在其他语言上很难(除了SQL)看到如此语义化的代码,简直就是一句赤裸裸的英文句子,这也是我向往的终极代码编程方式 —— 代码就是很直白的英文句子(当然也可以中文)。
3、 类似于数组的push在python中是append,n - - 在python中没有,python只能是n -= 1等这些小改动,对于我们来说其实都不能说是负担。
4、 JavaScript最大的特点就是你几乎开箱即用,很多功能都内置了,而Python其实也是,只不过没有全部放在名称空间里(你可以理解成全局作用域),比如数学的math,随机数的random,正则的re。它们都是需要import进来的。比如下面这样:
import math
import numpy
import re
import random
from functools import reduce
5、 你有没发现这些import跟JavaScript非常相似,甚至关键词都一样的,是的,这里你几乎可以用JavaScript的模块化思想来类比,你可以很容易理解并掌握它。
好了,虽说仅仅只是简单的一个问题解决过程,但你可以掌握不少这方面的语法与思想了吧。
这时候对于这一个问题的解决思路我抱着一丝疑惑,按照这样的方式,是不是存在着新出的随机号码可能已经存在于幸运者队列中了,假如这时候我要抽取的是50位呢?是不是无形中冲突的概率大大的增加?假如是抽99位(当然这时候就变成抽1位了),那是不是新出的随机数一直迎面撞到数组里?然后就一直随机一直撞,想一下都累。有木有新的方式来解决呢?这是肯定的。
这时候我们做的就是先生成一个全部参与者号码组成的数组,先随机抽取出一位,这时候数组就将这一位移除,接着继续抽取下一位,值得指定人数的幸运者选出即停止。
看看下面的代码:
// the second solution —— 利用数组机制
const randomNums = (a, b, n) => {
let arrList = Array.from({length: b - a}, (item, index) => index + a), res = []; while(n --) { let i = Math.floor(Math.random() * arrList.length); res.push(arrList[i]); arrList.splice(i, 1); } return res;
}
return randomNums(1, 100, 5);
在看一下Python的代码:
the second solution
def randomNums(a, b, n):
all = list(range(a, b))
res = []
while n:
index = math.floor(random.random() * len(all))
res.append(all[index])
del all[index]
n -= 1
return res
return randomNums(1, 100, 5)
解决思路的话其实没啥差别。只不过这里你可以发现:
1、 我们数组的删除某些成员用的是splice,其实还不是那么的直观,看看Python
del all[index]
直接就是一句delete,删除,看着就有种莫名的爽。
2、 Python生成list也非常简单,比之JavaScript更为简洁。
// JavaScript
let arrList = Array.from({length: b - a}, (item, index) => index + a)
Python
arrList = list(range(a, b))
接下来我们遇到的第二个问题是 —— Fizz Buzz。
来看一下问题的描述:
Fizz Buzz
难度
给定一个 数字 作为输入值, 打印出从 1 到给定数字的所有整数。
但是,当整数可以被 2 整除时,打印出“Fizz”; 当它可以被3整除时,打印出“Buzz”;
为了方便,可以将结果先合并成一个数组一起输出
这个采用JavaScript解决的话,我们几乎可以不假思索的写出:
const fizzBuzz = num => {
let arr = Array.from({length: num}, (item, index) => index + 1); // 先生成一个从1至输入值的数组 return arr.map(item => item % 2 === 0 ? 'Fizz' : item % 3 === 0 ? 'Buzz' : item); // 做一次map映射
}
console.log(fizzBuzz(20));
假如采用的是python呢?看看哈:
def _20191021():
def mapRes (item):
return 'Fizz' if item % 2 == 0 else 'Buzz' if item % 3 == 0 else item
def fizzBuzz(n):
all = list(range(1, n + 1))
return list(map(mapRes, all))
return fizzBuzz(20)
看起来好像也很相似,也有map,也是将一个函数作为参数传进map,是不是很cool?
1、 Python也有map,而且用法几乎和我们JavaScript一模一样,只不过它没有JavaScript这样的非常典型的链式调用。而且Python中的map对应的回调函数中,也没有index的值。另外就是map直接存在于名称空间,无需引入任何的包。
// JavaScript
let arr = [1,2,3,4]
arr.map(item => item ** 2);
Python
arr = [1,2,3,4]
def fn (item):
return item ** 2
map(fn, arr)
2、 看到上面的两段代码,你是不是也发现了Python的注释?Python里的注释跟很多的配置文件(比如nginx)一样用“#”作为注释的关键词,当然它还有" “、”’ '"这样的注释,可以自个去看看吧。
3、 看到上面的JavaScript代码好像用到了三元运算符,而Python中怎么不写呢?其实不是不想写,是Python中的三元是这样的,反正看起来不像三元运算。
res = a if fn else b # 就是说 res 如果满足fn 那就是a,否则就是b
当然了,你完全可以(尽管你可能在代码评审时被各种爆锤)
res = a if fn1 else b if fn2 else c if fn3 else d if fn4 else e ....
4、 Python再怎样,毕竟也是一门强类型的语言,对于类型检查也是非常注重的哈,你没办法将一个数字型的与一个字符串型的数据强行合并。
比如我们在JavaScript中很常见的:
let a = 1, b = 'dorsey'; console.log(a + b)
请相信我,你这在Python中是会报错的。
所以假如你有这样的需要,那么你可以这样:
a = 1 b = 'dorsey' print(str(a) + b)
其实就是做一步在强类型语言中非常常见的类型强制转换。不过最好还是在定义时更规范更有前瞻性的去选择类型。
学习JavaScript时,你是不是也会时不时的去浏览器将各大类型的内置对象(比如Object,Array,String…)打印一下,看看它们的原型,看看是否增加了什么新东西?
而Python呢,其实相较于JavaScript那些方法或对象,要更加复杂,内置的模块池也更加的庞大。你可以看看:
光一个最外层的文件目录就有这么多了,还得说可能有目录套目录等等,比如你看到__XXX__这样的变量,基本就是一个内部的对象了。
当然了,正如开头所说,这样一个个API去试是很累的方式,但不代表我们不可以全部浏览一遍,对吧?
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
前端工程师一般喜欢逛什么网站,都学哪些重要的内容?
几年前, jQuery + Bootstrap可以说是一统江湖,是前端领域的绝对霸主。而这几年,随着Angular、React、Vue等框架的兴起,变成了百家争鸣的局面。这几年,Web 前端的技术发展真是太快了,相应地,技术栈也就变得非常多,除了最基本的HTML/CSS/JavaScript,以及Vue/React/Angular等这些 JavaScript 框架和各自的生态体系,还有 CSS 预处理器Sass/Less/Stylus,还有TypeScript,还有grunt/webpack/gulp等各种打包构建工具,还有其他一大堆技术栈。这么多技术栈,我们不可能全都掌握,就算是资深的前端工程师,也只是精通其中一部分,接下来我给大家推荐一些我自己比较常看的书籍以及网站。 一. 书籍方面 1. HTML 和 CSS 基础方面的,首推《Head First HTML与CSS》,编排设计通俗易懂,就连完全零基础的非 IT 人员都适合学习。不过,Head First 这本书没有涉及到 HTML5 和 CSS3 的更新内容。不过,Head First 有另一本书讲解了 HTML5,叫《H...
- 下一篇
Java String 对象,你真的了解了吗?
String 对象的实现 String对象是 Java 中使用最频繁的对象之一,所以 Java 公司也在不断的对String对象的实现进行优化,以便提升String对象的性能,看下面这张图,一起了解一下String对象的优化过程。 1. 在 Java6 以及之前的版本中 String对象是对 char 数组进行了封装实现的对象,主要有四个成员变量:char 数组、偏移量 offset、字符数量 count、哈希值 hash。 String对象是通过 offset 和 count 两个属性来定位 char[] 数组,获取字符串。这么做可以高效、快速地共享数组对象,同时节省内存空间,但这种方式很有可能会导致内存泄漏。 2. 从 Java7 版本开始到 Java8 版本 从 Java7 版本开始,Java 对String类做了一些改变。String类中不再有 offset 和 count 两个变量了。这样的好处是String对象占用的内存稍微少了些,同时 String.substring 方法也不再共享 char[],从而解决了使用该方法可能导致的内存泄漏问题。 3. 从 Java9 版本开...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS8安装Docker,最新的服务器搭配容器使用
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2全家桶,快速入门学习开发网站教程
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装