<video id="71low"></video>

            ITPub博客

            首頁 > 應用開發 > Python > 有Java基礎的程序員,是如何看待Python這位少女的?

            有Java基礎的程序員,是如何看待Python這位少女的?

            原創 Python 作者:千鋒Python唐小強 時間:2019-10-23 17:05:48 0 刪除 編輯

            隨著人工智能的火熱,Python作為這塊領域中的佼佼者,也得到了迅猛的發展。作為一門強類型的動態腳本語言,Python與JavaScript非常相似,無論是語法思維上還是可用的基礎工具(內置API)上,對于寫慣了JavaScript的我們來說, Python非常的友好,友好在哪呢?我們一起來看看吧。

            由于我們都是有JavaScript基礎了,所以學習Python的方式得做一些小改變,不需要去看文檔學習API,那樣其實蠻累的,畢竟脫離了生產的學習API,就猶如聽著昏昏欲睡,毫無感情的色彩的四六級聽力,嚼著一段段生搬硬套硬湊生詞的閱讀理解,你很難真正的聽懂、讀懂它。(有幸在車站跟外國人交流過,他們說的話聽起來真的 很優美,很靈動,這跟一直是第一聲的四六級完全不同,好吧,扯遠了)

            學Python,我的理解 —— 就像學JQuery,學會一個$(id class tag),理解它比原生JS對于DOM操作的簡化就夠了,其他的五花八門的API,你在生產環境下用上一遍,自然而然就會了。

            這里我們也是一樣,不學習它的API,我們用Python來解決問題,解著解著,你自然也就會了,而且可以讓你的頭發少掉那么幾根。= =

            有Java基礎的程序員,是如何看待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那些方法或對象,要更加復雜,內置的模塊池也更加的龐大。你可以看看:

            有Java基礎的程序員,是如何看待Python這位少女的?

            光一個最外層的文件目錄就有這么多了,還得說可能有目錄套目錄等等,比如你看到__XXX__這樣的變量,基本就是一個內部的對象了。

            當然了,正如開頭所說,這樣一個個API去試是很累的方式,但不代表我們不可以全部瀏覽一遍,對吧?


            來自 “ ITPUB博客 ” ,鏈接:http://www.ep4tq.com/69923331/viewspace-2661162/,如需轉載,請注明出處,否則將追究法律責任。

            請登錄后發表評論 登錄
            全部評論

            注冊時間:2019-05-14

            • 博文量
              482
            • 訪問量
              259073
            妹子图每日分享