Python for 循環中 in 關鍵字含義是什麼?
最常用的情況下,我理解,比如
for i in range(1, 5):
print i
這裡用了 in 等同於把 range 返回的 list 裡面的每個元素逐個返回。
我覺得這個內在是不是應該調用了 list 的某個函數做到的?第二個問題。如果我有一個 file 文件 f,然後也用 for 循環遍歷每一行,應該可以這樣:
for row in f:
print row
那這裡 row 又是什麼類型呢?f 中的每一行作為什麼類型返回呢?感覺問題又回到了是不是應該有一個函數來響應in關鍵字並返回一個對象給前面的變數啊?
關鍵詞:迭代器
簡單來說,for in 語句是一個語法糖,具體是這樣的:- 調用一個對象的 __iter__ 方法,方法會返回一個迭代器,所謂迭代器就是實現了 __next__ 方法的對象,如果一個對象本身就實現了 __next__(Python 2 中是直接 「next」 方法,沒有下劃線) ,可以直接返回自身。
- 調用迭代器的 __next__ 返回迭代器中的「下一個」元素,比如說第一次調用會返回 0,第二次會返回 1,如此這般。
- 最後沒有元素了,迭代器拋出一個異常來表明自己沒有元素了。for 語句會捕獲這個異常並停下來。
我建議你獨立寫一個斐波那契的迭代器。
Mac 怎麼讓截圖變正常大小啊 QAQ
另外,還有一個銷魂的東西叫做生成器,演示一下如何優雅地斐波那契:(此後的代碼為了簡潔我都用 Python 3 來寫,用 Python 2 能運行但是性能糟糕。)def fib(n):
a = 0
b = 1
for _ in range(n):
a, b = b, a+b
yield a
這東西怎麼說呢,能把函數變成一個迭代器,yield 就類似 return,用 next() 來訪問 yield 的返回值,區別是一般的函數 return 完了就完了,但是 yield 返回數據以後,就相當於給函數目前的運行狀態存了檔,下一次調用 next() 的時候函數不會從頭執行,而是會從上次存檔的地方執行,直到再次遇到 yield ,存檔返回數據。
你可以多次調用 next() 求值直到不再 yield 數據,也就是說你調用我的斐波那契函數可以這樣:for n in fib(10000):
print(n)
# or
sum(fib(10000))
sum(map(lambda x: x*x, fib(42)))
謝邀。剛看到問題以為樓主要問in是什麼意思。這個for實際上就是迭代,使用的是迭代器(Iterator)。
# 以下代碼在Python 2中運行
for row in f:
print row
# 完全等價於
itr = f.__iter__() # 獲得新的迭代器
while True:
try:
row = itr.next()
except StopIteration:
break
print row
當然了,為了保證Python 2/3的兼容性,上面的代碼應該這樣寫
itr = iter(f)
while True:
try:
row = next(itr)
except StopIteration:
break
print(row)
所有可以迭代的類裡面都會有__iter__方法,用來返回一個迭代器。
迭代器就是一個實現了__next__方法(Python 2里是next方法)的類,每次調用__next__都會返回該容器的下一個值,且迭代器前進1。若已經沒有元素了,就拋出StopIteration異常。引用:
- Python 2中的相關文檔:5. Built-in Types
- Python 3中的相關文檔:4. Built-in Types
迭代器。
將 用dis轉成虛擬機的指令發現就是GET_ITER, FOR_ITER之類
這都是把range(1:5)和f當成容器來看。文件f既然有行,那row自然是字元串了。
就個人理解:in 關鍵字實現了一套python中的遍歷協議.
- 協議A: __iter__ + next
循環時, 程序先使用__iter__ (相當於iter(instance))獲取具有next方法的對象, 然後通過其返回的對象, 不斷調用其next方法, 直到StopIteration錯誤拋出.
class A:
def __iter__(self):
self.limit = 4
self.times = 0
self.init = 1
return self
def next(self):
if self.times &>= self.limit:
raise StopIteration()
else:
x = self.init
self.times += 1
self.init += 1
return x
print "A&>&>&>&>&>&>"
for x in A():
print x
列印結果:
A&>&>&>&>&>&>
1
2
3
4
- 協議B: __getitem__ + __len__
循環時, 程序先調用__len__ (相當於len(instance))方法獲取長度, 然後循環使用 __getitem__(index) (相當於instance[index])獲取元素, index in range(len(instance))
class B:
def __init__(self):
self._list = [5, 6, 7, 8]
def __getitem__(self, slice):
return self._list[slice]
def __len__(self):
return len(self._list)
print "B&>&>&>&>&>&>"
for x in B():
print x
列印結果:
B&>&>&>&>&>&>
5
6
7
8
- 協議C: yield關鍵字
def C():
for x in range(9, 13):
yield x
print "C&>&>&>&>&>&>"
for x in C():
print x
列印結果:
C&>&>&>&>&>&>
9
10
11
12
從上邊可以看出, ABC三種方式都可以實現in的循環, 對於A和B, 如果一個類把這兩個方案都實現了怎麼辦?
class D(A, B):
pass
print "D&>&>&>&>&>&>"
for x in D():
print x
列印結果:
D&>&>&>&>&>&>
1
2
3
4
可見, in優先使用的是A計劃.
仍在學習python中, 錯誤之處還請指點我剛學python,看了樓上大神們的回答感覺還是有點懵逼,我來說下我怎麼理解的,如果錯了,望大神糾正
in的意思是遍歷目錄里的數據
&>&>&> i = ["1","2"]
&>&>&> for j in i:
print(j)
...
1
2
等價於:
&>&>&> i = ("fuck","up")
&>&>&> j = 0
&>&>&> while j &< len(i):
print(i[j])
j = j+1
...
fuck
up
推薦閱讀:
※如何學習遞歸呢?
※有沒有程序或代碼可以直接破壞計算機的硬體?
※typedef void(*Fun) (void)是什麼意思?
※C++的語言設計有哪些缺陷?
※如何入門Python3?
TAG:編程語言 | Python | 編程 | Python3x | Python使用技巧 |