เหมือนภาษาโปรแกรมมิ่งส่วนใหญ่ Python มีคำสั่ง while และ for เพื่อสร้างโครงสร้างลูป คำสั่ง for มีประโยชน์โดยเฉพาะสำหรับการเดินทางผ่าน iterables เช่น ลิสต์, ทูเพิล หรือสตริง เครื่องมือการวนซ้ำที่มีประสิทธิภาพและรวดเร็วยิ่งขึ้นถูกกำหนดในโมดูล itertools ของไลบรารีมาตรฐาน Python บล็อกสร้าง iterator นี้เป็นการนำไปใช้แบบ Pythonic ของเครื่องมือคล้ายกันในภาษาโปรแกรมมิ่งเชิงฟังก์ชันเช่น Haskell และ SML
ฟังก์ชันในโมดูล itertools มี 3 ประเภท:
- Infinite iterators (ตัววนซ้ำอนันต์)
- Finite iterators (ตัววนซ้ำจำกัด)
- Combinatoric iterators (ตัววนซ้ำแบบจัดหมู่)
ฟังก์ชันต่อไปนี้สร้างลำดับอนันต์:
count() - ฟังก์ชันนี้คืนค่า iterator ของค่าที่มีระยะห่างเท่ากันจากค่าเริ่มต้น ฟังก์ชันนี้สามารถมีค่า step ตัวเลือกเพื่อเพิ่มค่าต่อไปโดยช่วงนี้:
>>> from itertools import count >>> for x in count(20): ... print(x) >>> for x in count(100, 10): ... print(x)
คำสั่งแรกจะสร้างลำดับอนันต์เริ่มจาก 20 และคำสั่งที่สองจะสร้างตัวเลขจาก 100 ด้วยความถี่ขั้น 10 สังเกตว่าลูปเป็นอนันต์และจะไม่สิ้นสุดด้วยตัวเอง จะสิ้นสุดเมื่อกด Ctrl-C
cycle() - ฟังก์ชันนี้เริ่มคืนค่าแต่ละองค์ประกอบจาก iterable ที่ให้มา และเก็บสำเนาไว้ เมื่อองค์ประกอบหมด องค์ประกอบในสำเนาจะถูกคืนค่า ทำให้เกิดลูปอนันต์:
>>> from itertools import cycle
>>> for x in cycle("hello"):
... print(x)
ตัวอักษรในสตริงจะถูกพิมพ์ซ้ำๆ จนกว่าจะมีการหยุดด้วย Ctrl-C
repeat() - ฟังก์ชันนี้คืนค่าอาร์กิวเมนต์อ็อบเจ็กต์ซ้ำๆ หากอาร์กิวเมนต์ที่สอง 'times' ถูกให้มา การซ้ำจะเกิดขึ้นจำนวนครั้งนั้น:
>>> from itertools import repeat
>>> for x in repeat(1):
... print(x)
>>> for x in repeat('hello', 10):
... print(x)
ลูปแรกจะพิมพ์ 1 อย่างไม่รู้จบ ลูปที่สองพิมพ์ 'hello' 10 ครั้ง
ฟังก์ชันในหมวดหมู่ต่อไปนี้คืนค่า finite iterators ที่สิ้นสุดลงบนลำดับอินพุตที่สั้นที่สุด:
accumulate() - ฟังก์ชันนี้มี 2 พารามิเตอร์ ตัวแรกคือ iterable (ลิสต์, ทูเพิล หรือสตริง) พารามิเตอร์ที่สองค่าเริ่มต้นคือ operator.add() (ฟังก์ชันในโมดูล operator นำไปใช้กับออปเปอเรเตอร์บวกมาตรฐาน) แต่อาจเป็นฟังก์ชันอื่นที่รับพารามิเตอร์ตัวเลข 2 ตัว:
accumulate(sequence, func)
องค์ประกอบ 2 ตัวแรกของลำดับอินพุทถูกประมวลผลโดย func ผลลัพธ์ของการประมวลผลเป็นพารามิเตอร์แรกสำหรับรอบถัดไป และพารามิเตอร์ที่สองของ func คือองค์ประกอบที่ 3 ในลำดับอินพุท กระบวนการนี้ทำซ้ำจนลำดับหมด ฟังก์ชัน accumulate คืนค่า iterator ที่แต่ละองค์ประกอบเป็นผลลัพธ์สะสมของการประมวลผลองค์ประกอบติดต่อกัน
ในตัวอย่างต่อไปนี้ ตัวเลขในลิสต์ถูกบวกสะสม สังเกตว่าอาร์กิวเมนต์ฟังก์ชันค่าเริ่มต้นคือการดำเนินการบวก:
>>> from itertools import accumulate >>> list(accumulate([1, 2, 3, 4, 5])) [1, 3, 6, 10, 15]
เราสามารถมีฟังก์ชันที่กำหนดเองเป็นพารามิเตอร์ที่สองของ accumulate():
>>> def multiply(x, y): ... return x * y >>> list(accumulate([1, 2, 3, 4, 5], multiply)) [1, 2, 6, 24, 120]
พฤติกรรมนี้คล้ายกับฟังก์ชันสำเร็จรูป reduce() ฟังก์ชัน reduce() คืนค่าเฉพาะผลลัพธ์สุดท้ายของการสะสม ในขณะที่ accumulate() สร้าง iterator ของผลลัพธ์ระหว่างทางทั้งหมด
chain() - ฟังก์ชันนี้สามารถมี iterables มากกว่าหนึ่งเป็นพารามิเตอร์ มัน yield แต่ละองค์ประกอบของ iterable แรกเข้า iterator ผลลัพธ์ และดำเนินต่อไปจนกว่าพารามิเตอร์ iterable จะหมด:
>>> from itertools import chain >>> list(chain([10, 20], 'hello', range(4))) [10, 20, 'h', 'e', 'l', 'l', 'o', 0, 1, 2, 3]
dropwhile() - ฟังก์ชันนี้คืนค่า iterator โดยการ drop องค์ประกอบจาก iterable นานเท่าที่ฟังก์ชัน predicate อาร์กิวเมนต์คืนค่า true ทันทีที่ฟังก์ชันคืนค่า false องค์ประกอบที่เหลือทั้งหมดจะถูก yield ให้ iterator:
>>> from itertools import dropwhile >>> def iseven(x): ... if x % 2 == 0: ... return True ... else: ... return False >>> list(dropwhile(iseven, [12, 90, 61, 4, 15])) [61, 4, 15]
filterfalse() - ฟังก์ชันนี้คืนค่า iterator โดยการกรององค์ประกอบที่ฟังก์ชัน predicate ให้ผลเป็น False:
>>> from itertools import filterfalse >>> def iseven(x): ... if x % 2 == 0: ... return True ... else: ... return False >>> list(filterfalse(iseven, [12, 90, 61, 4, 15])) [61, 15]
islice() - ฟังก์ชันนี้สร้าง iterator โดยการเลือกองค์ประกอบบางส่วนจาก iterable เกณฑ์การเลือกขึ้นอยู่กับพารามิเตอร์ start, stop และ step การเลือกเริ่มจากค่า start และดำเนินต่อจนถึงค่า stop หาก stop เป็น None จะไปจนถึงท้าย iterable มิฉะนั้น การเลือกจะหยุดที่ดัชนีที่ระบุ พารามิเตอร์ step ค่าเริ่มต้นคือ 1 การเลือกองค์ประกอบเพิ่มขึ้นตามพารามิเตอร์ step ไม่มีพารามิเตอร์ใดที่สามารถเป็นลบได้:
>>> from itertools import islice >>> list(islice(range(10), 1, 5, 2)) [1, 3] >>> list(islice(range(10), 0, None, 3)) [0, 3, 6, 9] >>> list(islice(range(10), 5, None)) [5, 6, 7, 8, 9] >>> list(islice(range(10), 5)) [0, 1, 2, 3, 4]
ฟังก์ชันต่อไปนี้สร้าง Combinatoric iterators จากอ็อบเจ็กต์ iterable:
product() - ฟังก์ชันนี้สร้าง iterator ซึ่งเป็น Cartesian product ขององค์ประกอบในลำดับอินพุท นี่เทียบเท่ากับการสร้าง nested for loops หนึ่งสำหรับการเดินทางแต่ละ iterable sequence:
ในตัวอย่างต่อไปนี้ เทคนิค list comprehension ถูกใช้เพื่อรัน nested loops 2 ชั้นบน 2 ลำดับเพื่อสร้าง Cartesian product:
>>> [[x, y] for x in [1, 2, 3] for y in ['a', 'b', 'c']] [[1, 'a'], [1, 'b'], [1, 'c'], [2, 'a'], [2, 'b'], [2, 'c'], [3, 'a'], [3, 'b'], [3, 'c']]
ฟังก์ชัน product() ให้ผลลัพธ์คล้ายกัน:
>>> from itertools import product >>> list(product([1, 2, 3], ['a', 'b', 'c'])) [(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b'), (2, 'c'), (3, 'a'), (3, 'b'), (3, 'c')]
permutations() - ฟังก์ชันนี้ yield ทุก permutation ที่เป็นไปได้ขององค์ประกอบใน iterable อินพุท ความยาวของแต่ละ permutation อาจระบุเป็นพารามิเตอร์ที่สอง หากไม่ระบุ ความยาวคือ 1:
>>> list(permutations(range(1, 4), 2)) [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]
combinations() - ฟังก์ชันนี้ yield ทุก combination ที่เป็นไปได้ขององค์ประกอบใน iterable อินพุท ความยาวของแต่ละ permutation อาจระบุเป็นพารามิเตอร์ที่สอง หากไม่ระบุ ความยาวคือ 1:
>>> from itertools import combinations >>> list(combinations(range(1, 4), 2)) [(1, 2), (1, 3), (2, 3)]
บทความนี้แนะนำเครื่องมือ iterator ต่างๆ ที่กำหนดในโมดูล itertools ของไลบรารี Python