您好,登錄后才能下訂單哦!
隨著人工智能的火熱,Python作為這塊領(lǐng)域中的佼佼者,也得到了迅猛的發(fā)展。作為一門強(qiáng)類型的動(dòng)態(tài)腳本語(yǔ)言,Python與JavaScript非常相似,無(wú)論是語(yǔ)法思維上還是可用的基礎(chǔ)工具(內(nèi)置API)上,對(duì)于寫慣了JavaScript的我們來(lái)說, Python非常的友好,友好在哪呢?我們一起來(lái)看看吧。
由于我們都是有JavaScript基礎(chǔ)了,所以學(xué)習(xí)Python的方式得做一些小改變,不需要去看文檔學(xué)習(xí)API,那樣其實(shí)蠻累的,畢竟脫離了生產(chǎn)的學(xué)習(xí)API,就猶如聽著昏昏欲睡,毫無(wú)感情的色彩的四六級(jí)聽力,嚼著一段段生搬硬套硬湊生詞的閱讀理解,你很難真正的聽懂、讀懂它。(有幸在車站跟外國(guó)人交流過,他們說的話聽起來(lái)真的 很優(yōu)美,很靈動(dòng),這跟一直是第一聲的四六級(jí)完全不同,好吧,扯遠(yuǎn)了)
學(xué)Python,我的理解 —— 就像學(xué)JQuery,學(xué)會(huì)一個(gè)$(id class tag),理解它比原生JS對(duì)于DOM操作的簡(jiǎn)化就夠了,其他的五花八門的API,你在生產(chǎn)環(huán)境下用上一遍,自然而然就會(huì)了。
這里我們也是一樣,不學(xué)習(xí)它的API,我們用Python來(lái)解決問題,解著解著,你自然也就會(huì)了,而且可以讓你的頭發(fā)少掉那么幾根。= =
我們遇到的第一個(gè)問題是 —— 抽獎(jiǎng)。
用JavaScript寫抽獎(jiǎng)你肯定信手拈來(lái),呼啦啦看著那個(gè)大轉(zhuǎn)盤咕嚕咕嚕就是一頓猛操作。這里我們只取其中最重要的一部分,也就是搖出幸運(yùn)者的邏輯。我們可以把它抽象成下面這樣:
1、抽獎(jiǎng)箱里的號(hào)碼為員工號(hào)碼,我們看成一個(gè)數(shù)組,假設(shè)這時(shí)候的員工號(hào)碼為1~100號(hào)。
2、抽獎(jiǎng)到的那位不能再繼續(xù)參與抽獎(jiǎng)。
3、假設(shè)我們要抽取若干位幸運(yùn)者(比如5位幸運(yùn)者)
這時(shí)候我們想:先建一個(gè)數(shù)組來(lái)裝幸運(yùn)者,接著隨機(jī)一個(gè)從1-100號(hào)的數(shù)字,并且判定一下這個(gè)隨機(jī)出來(lái)的數(shù)字是否在幸運(yùn)者數(shù)組中,如果沒有就加進(jìn)去,有就重新隨機(jī)。
我們先來(lái)看一下我們熟悉的JavaScript,基本上你可以發(fā)現(xiàn)有條不紊的按照我們的思路進(jìn)行著。
const randomNums_0 = (a, b, n) => { // 建一個(gè)數(shù)組 let res = []; // 生成 a~b 的隨機(jī)號(hào)碼 const createRandom = (a, b) => Math.floor(Math.random() * (b - a) + a); while(n) { let val = createRandom(a, b); if(res.indexOf(val) === -1) { // 如果這個(gè)隨機(jī)的號(hào)碼在幸運(yùn)者的隊(duì)列中不存在 res.push(val); // 則將這個(gè)號(hào)碼添加進(jìn)去 n --; // 這里的n是幸運(yùn)者的人數(shù),當(dāng)隊(duì)列中多了一個(gè)幸運(yùn)者,n就減一 } // 否則重新生成隨機(jī)數(shù) } return res; } console.log(randomNums_0(1, 100, 5));
這時(shí)做過了一遍之后,再返回來(lái)看看Python版。(這里的Python是Python3.7,對(duì)于Python2的語(yǔ)法異同(語(yǔ)法不兼容其實(shí)不少,最常見的比如Python2的print ***與Python3的 print(***)。這里就不說了,只說Python3。)
# 簡(jiǎn)單抽獎(jiǎng) —— 生成n個(gè)輸入范圍在a ~ b內(nèi)的不同隨機(jī)整數(shù)。 # 難度 ★★ # 函數(shù)接收3個(gè)數(shù)字,分別為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))
基本的套路其實(shí)一模一樣,只不過稍微語(yǔ)法不同:
1、 JavaScript的函數(shù)定義是通過function,或者通過箭頭表達(dá)式。而Python則是通過def。def其實(shí)就是定義的意思,define嘛。
// JavaScript function fn () { ... } const fn = argus => { ... } # Python def fn ():
python的函數(shù)沒有大括號(hào)包裹,而是通過":"來(lái)做判定。
2、 我們的判斷數(shù)組是否包含某個(gè)成員,我們的初步思路就是判斷它的索引是不是大于-1,這里Python做得更好,它直接就是:
if num not in res:
你在其他語(yǔ)言上很難(除了SQL)看到如此語(yǔ)義化的代碼,簡(jiǎn)直就是一句赤裸裸的英文句子,這也是我向往的終極代碼編程方式 —— 代碼就是很直白的英文句子(當(dāng)然也可以中文)。
3、 類似于數(shù)組的push在python中是append,n - - 在python中沒有,python只能是n -= 1等這些小改動(dòng),對(duì)于我們來(lái)說其實(shí)都不能說是負(fù)擔(dān)。
4、 JavaScript最大的特點(diǎn)就是你幾乎開箱即用,很多功能都內(nèi)置了,而Python其實(shí)也是,只不過沒有全部放在名稱空間里(你可以理解成全局作用域),比如數(shù)學(xué)的math,隨機(jī)數(shù)的random,正則的re。它們都是需要import進(jìn)來(lái)的。比如下面這樣:
import math import numpy import re import random from functools import reduce
5、 你有沒發(fā)現(xiàn)這些import跟JavaScript非常相似,甚至關(guān)鍵詞都一樣的,是的,這里你幾乎可以用JavaScript的模塊化思想來(lái)類比,你可以很容易理解并掌握它。
好了,雖說僅僅只是簡(jiǎn)單的一個(gè)問題解決過程,但你可以掌握不少這方面的語(yǔ)法與思想了吧。
這時(shí)候?qū)τ谶@一個(gè)問題的解決思路我抱著一絲疑惑,按照這樣的方式,是不是存在著新出的隨機(jī)號(hào)碼可能已經(jīng)存在于幸運(yùn)者隊(duì)列中了,假如這時(shí)候我要抽取的是50位呢?是不是無(wú)形中沖突的概率大大的增加?假如是抽99位(當(dāng)然這時(shí)候就變成抽1位了),那是不是新出的隨機(jī)數(shù)一直迎面撞到數(shù)組里?然后就一直隨機(jī)一直撞,想一下都累。有木有新的方式來(lái)解決呢?這是肯定的。
這時(shí)候我們做的就是先生成一個(gè)全部參與者號(hào)碼組成的數(shù)組,先隨機(jī)抽取出一位,這時(shí)候數(shù)組就將這一位移除,接著繼續(xù)抽取下一位,值得指定人數(shù)的幸運(yùn)者選出即停止。
看看下面的代碼:
// the second solution —— 利用數(shù)組機(jī)制 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)
解決思路的話其實(shí)沒啥差別。只不過這里你可以發(fā)現(xiàn):
1、 我們數(shù)組的刪除某些成員用的是splice,其實(shí)還不是那么的直觀,看看Python
del all[index]
直接就是一句delete,刪除,看著就有種莫名的爽。
2、 Python生成list也非常簡(jiǎn)單,比之JavaScript更為簡(jiǎn)潔。
// JavaScript let arrList = Array.from({length: b - a}, (item, index) => index + a) # Python arrList = list(range(a, b))
接下來(lái)我們遇到的第二個(gè)問題是 —— Fizz Buzz。
來(lái)看一下問題的描述:
# Fizz Buzz # 難度 ★★ # 給定一個(gè) 數(shù)字 作為輸入值, 打印出從 1 到給定數(shù)字的所有整數(shù)。 # 但是,當(dāng)整數(shù)可以被 2 整除時(shí),打印出“Fizz”; 當(dāng)它可以被3整除時(shí),打印出“Buzz”; # 為了方便,可以將結(jié)果先合并成一個(gè)數(shù)組一起輸出
這個(gè)采用JavaScript解決的話,我們幾乎可以不假思索的寫出:
const fizzBuzz = num => { let arr = Array.from({length: num}, (item, index) => index + 1); // 先生成一個(gè)從1至輸入值的數(shù)組 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)
看起來(lái)好像也很相似,也有map,也是將一個(gè)函數(shù)作為參數(shù)傳進(jìn)map,是不是很cool?
1、 Python也有map,而且用法幾乎和我們JavaScript一模一樣,只不過它沒有JavaScript這樣的非常典型的鏈?zhǔn)秸{(diào)用。而且Python中的map對(duì)應(yīng)的回調(diào)函數(shù)中,也沒有index的值。另外就是map直接存在于名稱空間,無(wú)需引入任何的包。
// 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、 看到上面的兩段代碼,你是不是也發(fā)現(xiàn)了Python的注釋?Python里的注釋跟很多的配置文件(比如nginx)一樣用“#”作為注釋的關(guān)鍵詞,當(dāng)然它還有" “、”’ '"這樣的注釋,可以自個(gè)去看看吧。
3、 看到上面的JavaScript代碼好像用到了三元運(yùn)算符,而Python中怎么不寫呢?其實(shí)不是不想寫,是Python中的三元是這樣的,反正看起來(lái)不像三元運(yùn)算。
res = a if fn else b # 就是說 res 如果滿足fn 那就是a,否則就是b
當(dāng)然了,你完全可以(盡管你可能在代碼評(píng)審時(shí)被各種爆錘)
res = a if fn1 else b if fn2 else c if fn3 else d if fn4 else e ....
4、 Python再怎樣,畢竟也是一門強(qiáng)類型的語(yǔ)言,對(duì)于類型檢查也是非常注重的哈,你沒辦法將一個(gè)數(shù)字型的與一個(gè)字符串型的數(shù)據(jù)強(qiáng)行合并。
比如我們?cè)贘avaScript中很常見的:
let a = 1, b = 'dorsey'; console.log(a + b)
請(qǐng)相信我,你這在Python中是會(huì)報(bào)錯(cuò)的。
所以假如你有這樣的需要,那么你可以這樣:
a = 1 b = 'dorsey' print(str(a) + b)
其實(shí)就是做一步在強(qiáng)類型語(yǔ)言中非常常見的類型強(qiáng)制轉(zhuǎn)換。不過最好還是在定義時(shí)更規(guī)范更有前瞻性的去選擇類型。
學(xué)習(xí)JavaScript時(shí),你是不是也會(huì)時(shí)不時(shí)的去瀏覽器將各大類型的內(nèi)置對(duì)象(比如Object,Array,String…)打印一下,看看它們的原型,看看是否增加了什么新東西?
而Python呢,其實(shí)相較于JavaScript那些方法或?qū)ο螅訌?fù)雜,內(nèi)置的模塊池也更加的龐大。你可以看看:
光一個(gè)最外層的文件目錄就有這么多了,還得說可能有目錄套目錄等等,比如你看到__XXX__這樣的變量,基本就是一個(gè)內(nèi)部的對(duì)象了。
當(dāng)然了,正如開頭所說,這樣一個(gè)個(gè)API去試是很累的方式,但不代表我們不可以全部瀏覽一遍,對(duì)吧?
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。