国产网曝门99视频在线看_免费看片a级毛片免费看_4hu四虎永久在线观看_高清无套内精线观看456_国产欧美亚洲日韩久久福利_av在线无码观看另类重口_欧美精品一二三区较多收藏_欧美老熟妇伦视频_婷婷六月综合激情_最新国产成人野战在线观看


值及其相應(yīng)的運算

    時間: 瀏覽:1979次  原文出處:xue.cn
導讀:歡迎你來到站長在線的站長書籍欄目,你正在學習的是李笑來著作的《自學是門手藝》一書中的《值及其相應(yīng)的運算》原文內(nèi)容如下:

導讀:歡迎你來到站長在線的站長書籍欄目,你正在學習的是李笑來著作的《自學是門手藝》一書中的《值及其相應(yīng)的運算》原文內(nèi)容如下:

值及其相應(yīng)的運算

從結(jié)構(gòu)上來看,一切的計算機程序,都由且只由兩個最基本的成分構(gòu)成:

  • 運算(Evaluation)
  • 流程控制(Control Flow)

沒有流程控制的是計算器而已;有流程控制的才是可編程設(shè)備。

看看之前我們見過的計算質(zhì)數(shù)的程序:(按一下 ?,即 ESC,確保已經(jīng)進入命令模式,? L 可以切換是否顯示代碼行號)

def is_prime(n): # 定義 is_prime(),接收一個參數(shù)
    if n < 2: # 開始使用接收到的那個參數(shù)(值)開始計算……
        return False # 不再是返回給人,而是返回給調(diào)用它的代碼……
    if n == 2:
        return True
    for m in range(2, int(n**0.5)+1):
        if (n % m) == 0:
            return False
    else:
        return True

for i in range(80, 110):
    if is_prime(i): # 調(diào)用 is_prime() 函數(shù),
        print(i) # 如果返回值為 True,則向屏幕輸出 i
83
89
97
101
103
107
109

if...,for... 在控制流程:在什么情況下運算什么,在什么情況下重復運算什么;

第 13 行 is_prime() 這個函數(shù)的調(diào)用,也是在控制流程 —— 所以我們可以*把函數(shù)看作是 “子程序” *;

一旦這個函數(shù)被調(diào)用,流程就轉(zhuǎn)向開始執(zhí)行在第 1 行中定義的 is_prime() 函數(shù)內(nèi)部的代碼,而這段代碼內(nèi)部還是 計算 和流程控制,決定一個返回值 —— 返回值是布爾值;再回到第 13 行,將返回值交給 if 判斷,決定是否執(zhí)行第 14 行……

而計算機這種可編程設(shè)備之所以可以做流程控制,是因為它可以做布爾運算,即,它可以對布爾值進行操作,而后將布爾值交給分支和循環(huán)語句,構(gòu)成了程序中的流程控制。

從本質(zhì)上看,程序里的絕大多數(shù)語句包含著運算(Evaluation),即,在對某個值進行評價。這里的 “評價”,不是 “判斷某人某事的好壞”,而是 “計算出某個值究竟是什么” —— 所以,我們用中文的 “運算” 翻譯這個 “_Evaluation_” 可能表達得更準確一些。

在程序中,被運算的可分為常量(Literals)和變量(Variables)。

a = 1 + 2 * 3
a += 1
print(a)

在以上代碼中,

12、3,都是常量。Literal 的意思是 “字面的”,顧名思義,常量的值就是它字面上的值。1 的值,就是 1

a 是變量。顧名思義,它的值將來是可變的。比如,在第 2 句中,這個變量的值發(fā)生了改變,之前是 7,之后變成了 8。

第 1 句中的 +*,是操作符(Operators),它用來對其左右的值進行相應(yīng)的運算而后得到一個值。先是由操作符 * 對 2 和 3 進行運算, 生成一個值,6;然后再由操作符 + 對 1 和 6 進行運算,生成一個值 7。先算乘除后算加減,這是操作符的優(yōu)先級決定的。

= 是賦值符號,它的作用是將它右邊的值保存到左邊的變量中。

值是程序的基礎(chǔ)成分(Building blocks),它就好像蓋房子用的磚塊一樣,無論什么樣的房子,到最后都主要是由磚塊構(gòu)成。

常量,當然有個值 —— 就是它們字面所表達的值。

變量必須先賦值才能使用,也就是說,要先把一個值保存到變量中,它才能在其后被運算。

python 中每個函數(shù)都有 返回值 ,即便你在定義一個函數(shù)的時候沒有設(shè)定返回值,它也會加上默認的返回值 None…… (請注意 None 的大小寫?。?/p>

def f():
    pass
print(f()) # 輸出 f() 這個函數(shù)被調(diào)用后的返回值,None
print(print(f())) # 這一行最外圍的 print() 調(diào)用了一次 print(f()),所以輸出一個 None,
                  # 而后再輸出這次調(diào)用的返回值,所以又輸出一次 None
None
None
None

當我們調(diào)用一個函數(shù)的時候,本質(zhì)上來看,就相當于:

我們把一個值交給某個函數(shù),請函數(shù)根據(jù)它內(nèi)部的運算和流程控制對其進行操作而后返回另外一個值。

比如,abs() 函數(shù),就會返回傳遞給它的 值 的絕對值;int() 函數(shù),會將傳遞給它的值的小數(shù)部分砍掉;float() 接到整數(shù)參數(shù)之后,會返回這個整數(shù)的浮點數(shù)形式:

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_Node_interactivity = "all"

abs(-3.14159)
int(abs(-3.14159))
float(int(abs(-3.14159)))
3.14159
3
3.0

值的類型

編程語言中,總是包含最基本的三種數(shù)據(jù)類型

  • 布爾值(Boolean Value)
  • 數(shù)字(Numbers):整數(shù)(Int)、浮點數(shù)(Float)、復數(shù)(complex Numbers)
  • 字符串(Strings)

既然有不同類型的數(shù)據(jù),它們就分別對應(yīng)著不同類型的值。

運算的一個默認法則就是,通常情況下應(yīng)該是 相同類型的值才能相互運算 。

顯然,數(shù)字與數(shù)字之間的運算是合理的,但你讓 + 這個操作符對一個字符串和一個數(shù)字進行運算就不行:

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

11 + 10 - 9 * 8 / 7 // 6% 5
'3.14' + 3 # 這一句會報錯
20.0
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-18-e922b7565e53> in <module>
      3 
      4 11 + 10 - 9 * 8 / 7 // 6 % 5
----> 5 '3.14' + 3                  # 這一句會報錯

TypeError: can only concatenate str (not "int") to str

所以,在不得不對不同類型的值進行運算之前,總是要事先做 Type Casting(類型轉(zhuǎn)換)。比如,

  • 將字符串轉(zhuǎn)換為數(shù)字用 int()、float();
  • 將數(shù)字轉(zhuǎn)換成字符串用 str()

另外,即便是在數(shù)字之間進行計算的時候,有時也需要將整數(shù)轉(zhuǎn)換成浮點數(shù)字,或者反之:

  • 將整數(shù)轉(zhuǎn)換成浮點數(shù)字用 float();
  • 將浮點數(shù)字轉(zhuǎn)換成整數(shù)用 int();

有個函數(shù),type(),可以用來查看某個值屬于什么類型:

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

type(3)
type(3.0)
type('3.14')
type(True)
type(range(10))
type([1,2,3])
type((1,2,3))
type({1,2,3})
type({'a':1, 'b':2, 'c':3})
int
float
str
bool
range
list
tuple
set
dict

操作符

針對不同類型的數(shù)據(jù),有各自專用的操作符。

數(shù)值操作符

針對數(shù)字進行計算的操作符有加減乘除商余冪:+-、*、///、%**。

其中 + 和 - 可以對單個值進行操作,-3;其它的操作符需要有兩個值才能操作。

從優(yōu)先級來看,這些操作符中:

  • 對兩個值進行操作的 +、- 的優(yōu)先級最低;
  • 稍高的是 *、///、%;
  • 更高的是對單個值進行操作的 +-;
  • 優(yōu)先級最高的是 **

完整的操作符優(yōu)先級列表,參見官方文檔:expressions

布爾值操作符

針對布爾值,操作符有、、and、or、not。

它們之中,優(yōu)先級最低的是或 or,然后是與 and, 優(yōu)先級最高的是非 not

True and False or not True

False

最先操作的是 not,因為它優(yōu)先級最高。所以,上面的表達式相當于 True and False or (not True),即相當于 True and False or False

然后是 and,所以,True and False or False 相當于是 (True and False) or False,即相當于 False or False;

于是,最終的值是 False。

邏輯操作符

數(shù)值之間還可以使用邏輯操作符,1 > 2 返回布爾值 False。邏輯操作符有:<(小于)、<=(小于等于)、>(大于)、>=(大于等于)、!=(不等于)、==(等于)。

邏輯操作符的優(yōu)先級,高于布爾值的操作符,低于數(shù)值計算的操作符。 即:數(shù)值計算的操作符優(yōu)先級最高,其次是邏輯操作符,布爾值的操作符優(yōu)先級最低。

n = -95
n < 0 and (n + 1) % 2 == 0

True

字符串操作符

針對字符串,有三種操作:

  • 拼接:+ 和 ' '(后者是空格
  • 拷貝:*
  • 邏輯運算:in、not in;以及,<、<=、>>=、!=、==
from IPython.core.interactiveshell import InteractiveShell

InteractiveShell.ast_node_interactivity = "all"



'Awesome' + 'Python'

'Awesome' 'Python'

'Python, ' + 'Awesome! ' * 3

'o' in 'Awesome' and 'o' not in 'Python'
'AwesomePython'
'AwesomePython'
'Python, Awesome! Awesome! Awesome! '
False

字符之間,字符串之間,除了 == 和 != 之外,也都可以被邏輯操作符 <、<=、>>= 運算:

'a' < 'b'

True

這是因為字符對應(yīng)著 Unicode 碼,字符在被比較的時候,被比較的是對應(yīng)的 Unicode 碼。

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

'A' > 'a'
ord('A')
ord('a')
False
65
97

當字符串被比較的時候,將從兩個字符串各自的第一個字符開始逐個比較,“一旦決出勝負馬上停止”:

'PYTHON' > 'Python 3'

False

列表的操作符

數(shù)字和字符串(由字符構(gòu)成的序列)是最基本的數(shù)據(jù)類型,而我們往往需要批量處理數(shù)字和字符串,這樣的時候,我們需要數(shù)組array)。不過,在 Python 語言中,它提供了一個容器(Container)的概念,用來容納批量的數(shù)據(jù)。

Python 的容器有很多種 —— 字符串,其實也是容器的一種,它的里面容納著批量的字符。

我們先簡單接觸一下另外一種容器:列表(List)。

列表的標示,用方括號 [];舉例來說,[1, 2, 3, 4, 5] 和 ['ann', 'bob', 'cindy', 'dude', 'eric'],或者 ['a', 2, 'b', 32, 22, 12] 都是一個列表。

因為列表和字符串一樣,都是 有序容器 (容器還有另外一種是無序容器),所以,它們可用的操作符其實相同:

  • 拼接:+(與字符串不一樣的地方是,不能用空格 ' ' 了)
  • 拷貝:*
  • 邏輯運算:innot in;以及,<、<=>、>=!=、==

兩個列表在比較時(前提是兩個列表中的數(shù)據(jù)元素類型相同),遵循的還是跟字符串比較相同的規(guī)則:“一旦決出勝負馬上停止”。但實際上,由于列表中可以包含不同類型的元素,所以,通常情況下沒有實際需求對他們進行 “大于、小于” 的比較。(比較時,類型不同會引發(fā) TypeError…… )

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

a_list = [1, 2, 3, 4, 5]
b_list = [1, 2, 3, 5]
c_list = ['ann', 'bob', 'cindy', 'dude', 'eric']
a_list > b_list
10 not in a_list
'ann' in c_list
False
True
True

更復雜的運算

對于數(shù)字進行加、減、乘、除、商、余、冪的操作,對于字符串進行拼接、拷貝、屬于的操作,對布爾值進行或、與、非的操作,這些都是相對簡單的運算。

更為復雜一點的,我們要通過調(diào)用函數(shù)來完成 —— 因為在函數(shù)內(nèi)部,我們可以用比 “單個表達式” 更為復雜的程序針對傳遞進來的參數(shù)進行運算。換言之,函數(shù)就相當于各種事先寫好的子程序,給它傳遞一個值,它會對其進行運算,而后返回一個值(最起碼返回一個 None)。

以下是 Python 語言所有的內(nèi)建函數(shù)(Built-in Functions):

(PythonBuilt-inFunctions)abs()delattr()hash()memoryview()set()
all()dict()help()min()setattr()
any()dir()hex()next()slice()
ascii()divmod()id()object()sorted()
bin()enumerate()input()oct()staticmethod()
bool()eval()int()open()str()
breakpoint()exec()isinstance()ord()sum()
bytearray()filter()issubclass()pow()super()
bytes()float()iter()print()tuple()
callable()format()len()property()type()
chr()frozenset()list()range()vars()
classmethod()getattr()locals()repr()zip()
compile()globals()map()reversed()__import__()
complex()hasattr()max()round()

現(xiàn)在倒不用著急一下子全部了解它們 —— 反正早晚都會的。

這其中,針對數(shù)字,有計算絕對值的函數(shù) abs(),有計算商余的函數(shù) divmod() 等等。

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

abs(-3.1415926)
divmod(11, 3)
3.1415926
(3, 2)

這些內(nèi)建函數(shù)也依然只能完成 “基本操作”,比如,對于數(shù)字,我們想計算三角函數(shù)的話,內(nèi)建函數(shù)就幫不上忙了,于是,我們需要調(diào)用標準庫(Standard Library)中的 math 模塊(Module):

import math
math.sin(5)
-0.9589242746631385

代碼 math.sin(5) 這里的 .,也可以被理解為 “操作符”,它的作用是:

從其它模塊中調(diào)用函數(shù)。

代碼 math.sin(5) 的作用是:

把 5 這個值,傳遞給 math 這個模塊里的 sin() 函數(shù),讓 sin() 根據(jù)它內(nèi)部的代碼對這個值進行運算,而后返回一個值(即,計算結(jié)果)。

類(Class)中定義的函數(shù),也可以這樣被調(diào)用 —— 雖然你還不明白類(Class)究竟是什么,但從結(jié)構(gòu)上很容易理解,它實際上也是保存在其他文件中的一段代碼,于是,那段代碼內(nèi)部定義的函數(shù),也可以這樣調(diào)用。

比如,數(shù)字,其實屬于一個類,所以,我們可以調(diào)用那個類里所定義的函數(shù),比如,float.as_integer_ratio(),它將返回兩個值,第一個值除以第二個值,恰好等于傳遞給它的那個浮點數(shù)字參數(shù):

3.1415926.as_integer_ratio()

3.1415926.as_integer_ratio()

關(guān)于布爾值的補充

當你看到以下這樣的表達式,而后再看看它的結(jié)果,你可能會多少有點迷惑:

True or 'Python'

True

這是因為 Python 將 True 定義為:

By default, an object is considered true unless its class defines either a __bool__() method that returnsFalseor a __len__() method that returns zero, when called with the object.

Python 官方文檔

這一段文字,初學者是看不懂的。但下一段就好理解了:

Here are most of the built-in objects consideredFalse:

  • constants defined to be false:NoneandFalse.
  • zero of any numeric type:0,0.0,0j,Decimal(0),Fraction(0, 1)
  • empty sequences and collections:'',(),[],{},set(),range(0)

所以,'Python' 是個非空的字符串,即,不屬于是 empty sequences,所以它不被認為是 False,即,它的布爾值是 True

于是,這么理解就輕松了:

每個變量或者常量,除了它們的值之外,同時還相當于有一個對應(yīng)的布爾值。

關(guān)于值的類型的補充

除了數(shù)字、布爾值、字符串,以及上一小節(jié)介紹的列表之外,還有若干數(shù)據(jù)類型,比如 range()(等差數(shù)列)、tuple元組)、set集合)、dictionary字典),再比如 Date Type(日期)等等。

它們都是基礎(chǔ)數(shù)據(jù)類型的各種組合 —— 現(xiàn)實生活中,更多需要的是把基礎(chǔ)類型組合起來構(gòu)成的數(shù)據(jù)。比如,一個通訊簿,里面是一系列字符串分別對應(yīng)著若干字符串和數(shù)字。

entry[3662] = {
    'first_name': 'Michael',
    'last_name': 'Willington',
    'birth_day': '12/07/1992',
    'mobile': {
        '+714612234',
        '+716253923'
    }
    'id': 3662,
    ...
}

針對不同的類型,都有相對應(yīng)的操作符,可以對其進行運算。

這些類型之間有時也有不得不相互運算的需求,于是,在相互運算之前同樣要 _Type Casting_,比如將 List 轉(zhuǎn)換為 Set,或者反之:

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

a = [1, 2, 3, 4, 5, 6, 7]
b = set(a)
c = list(b)
a
b
c
[1, 2, 3, 4, 5, 6, 7]
{1, 2, 3, 4, 5, 6, 7}
[1, 2, 3, 4, 5, 6, 7]

總結(jié)

回到最開始:從結(jié)構(gòu)上來看,一切的計算機程序,都由且只由兩個最基本的成分構(gòu)成:

  • 運算(Evaluation)
  • 流程控制(Control Flow)

這一章主要介紹了基礎(chǔ)數(shù)據(jù)類型的運算細節(jié)。而除了基礎(chǔ)數(shù)據(jù)類型,我們需要由它們組合起來的更多復雜數(shù)據(jù)類型。但無論數(shù)據(jù)的類型是什么,被操作符操作的總是該數(shù)據(jù)的。所以,雖然絕大多數(shù)編程書籍按照慣例會講解 “數(shù)據(jù)類型”,但為了究其本質(zhì),我們在這里關(guān)注的是 “值的類型”。雖然只是關(guān)注焦點上的一點點轉(zhuǎn)換,但實踐證明,這一點點的不同,對初學者更清楚地把握知識點有巨大的幫助。

針對每一種 值 的類型,無論簡單復雜,都有相應(yīng)的操作方式:

  • 操作符
  • 值運算
  • 邏輯運算
  • 函數(shù)
  • 內(nèi)建函數(shù)
  • 其他模塊里的函數(shù)
  • 其本身所屬類之中所定義的函數(shù)

所以,接下來要學習的,無非就是熟悉各種 數(shù)據(jù)類型 ,及其相應(yīng)的操作,包括能對它們的值進行操作的操作符和函數(shù);無論是操作符還是函數(shù),最終都會返回一個相應(yīng)的,及其相應(yīng)的布爾值 —— 這么看來,編程知識結(jié)構(gòu)沒多復雜。因為換句話講,

接下來你要學習的無非是各種 數(shù)據(jù)類型 的運算而已。

另外,雖然現(xiàn)在尚未來得及對函數(shù)進行深入講解,但最終你會發(fā)現(xiàn)它跟操作符一樣,在程序里無所不在。

備注

另外,以下幾個鏈接先放在這里,未來你會返回來參考它們,還是不斷地參考它們:

  • 關(guān)于表達式:
  • 關(guān)于所有操作的優(yōu)先級:
  • 上一條鏈接不懂 BNF 的話根本讀不懂:
  • Python 的內(nèi)建函數(shù):
  • Python 的標準數(shù)據(jù)類型:

另外,其實所有的操作符,在 Python 內(nèi)部也是調(diào)用函數(shù)完成的……



本文地址:http://003188.cn/zhijiqixiangyingdeyunsuan.html
碼字不易,打個賞唄
楊澤業(yè)感謝你的支持!

猜你喜歡