一,字典與循環
如果你在 for 語句里面用字典,程序會遍歷字典中的所有鍵。例如下面這個 print_hist 函數就輸出其中的每一個鍵與對應的鍵值:
$ cat c.py
#!/bin/python
def histogram(s):
d = dict()
for c in s:
if c not in d:
d[c] = 1
else:
d[c] += 1
return d
def print_hist(h):
for c in h:
print(c, h[c])
h = histogram('apple')
print(print_hist(h))
執行結果:
$ python3 c.py
a 1
p 2
l 1
e 1
None
二,全局變量
在主函數中的變量也叫全局變量,因為所有函數都可以訪問這些變量。局部變量在所屬的函數結束后就消失了,而主函數在其他函數調用結束后依然還存在。
一般常用全局變量作為 flag(標識);比如用來判斷一個條件是否成立的布爾變量之類的。比如有的程序用名字為 verbose 的標識變量,來控制輸出內容的詳細程度:
$ cat d.py
#!/bin/python
verbose = True
def example1():
if verbose:
print('Running example1')
如果你想給全局變量重新賦值,可以看看下面這個例子:
這幾行代碼的意圖,本來是想要追蹤確定函數是否被調用了:
$ cat d.py
#!/bin/python
been_called = False
def example2():
been_called = True
但運行后並不報錯,been_called的值也並不會變化。
這個情況的原因是 example2這個函數創建了一個新的名為been_called 的局部變量。函數結束之后,局部變量就釋放了,並不會影響全局變量。所以,要在函數內部來給全局變量重新賦值,必須要在使用之前聲明這個全局變量:
$ cat d.py
#!/bin/python
been_called = False
def example2():
global been_called #全局申明
been_called = True
global 那句代碼的效果是告訴解釋器:【在這個函數內,been_called 是個全局變量;不要創建一個同名的局部變量】
下面的例子中,試圖對全局變量進行更新:
$ cat d.py
#!/bin/python
count = 0
def example3():
count += 1
print(example3())
執行后報錯如下:
UnboundLocalError: local variable 'count' referenced before assignment(意思是未綁定局部錯誤:局部變量 count 未經賦值就被引用)
Python 會假設這個 count 是局部的,然后基於這樣的假設,就是在寫出該變量之前就試圖讀取;這樣問題的解決方法依然就是聲稱count 為全局變量:
count = 0
def example3():
global count
count += 1
如果全局變量指向的是一個可修改的值,你可以無需聲明該變量就直接修改:
known[2] = 1
所以你可以在全局的列表或者字典里面添加、刪除或者替換元素;但如果你要重新給這個全局變量賦值,就必須要聲明了:
雖然全局變量很有用,但不要總是修改全局變量的值,那樣會增加調試的難度。