บทความนี้แตกออกมาจาก https://phyblas.hinaboshi.com/20151217
การเปลี่ยนหน้าที่ของฟังก์ชันและตัวแปรนั้นเป็นความเปลี่ยนแปลงที่สำคัญอย่างหนึ่งที่เกิดขึ้นในไพธอน 3.x เมื่อเทียบกับไพธอน 2.x
หนึ่งในฟังก์ชันที่ถูกเปลี่ยนแปลงไปก็คือฟังก์ชัน range และมีฟังก์ชันหนึ่งที่หายไป นั่นก็คือ xrange นี่เป็นหัวข้อหนึ่งที่น่ายกมาพูดถึงสักหน่อย
ในไพธอน 2 นั้นมีฟังก์ชัน range กับ xrange ทั้ง ๒ ฟังก์ชันนี้ดูเผินๆแล้วคล้ายกันแต่มีความต่างกันเล็กน้อย
กล่าวคือ range เป็นฟังก์ชันสำหรับคืนค่าข้อมูลประเภทลิสต์ของจำนวนเต็มซึ่งมีค่าในช่วงตามที่กำหนดออกมา เช่น
print(range(10))
จะได้[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
ถ้าลองหาชนิดของข้อมูลprint(type(range(10))
จะได้
<type 'list'>
ในขณะที่ xrange นั้นจะให้สิ่งที่คล้ายกัน คือได้จำนวนเต็มที่มีค่าไล่เรียงในช่วงที่กำหนด อย่างไรก็ตามสิ่งที่ได้นั้นไม่ใช่ข้อมูลประเภทลิสต์ แต่เป็นชนิด xrange ซึ่งเป็นชนิดของมันเอง
print(xrange(10))
จะได้xrange(10)
พอลองถามหาชนิดของข้อมูล
print(type(xrange(10)))
จะได้<type 'xrange'>
จะเห็นว่า xrange ไม่ได้ให้ลิสต์ออกมา แต่ให้ข้อมูลที่เป็นชนิดของมันเองโดยเฉพาะ อย่างไรก็ตามหากลองprint([i for i in xrange(10)])
ก็จะพบว่าได้[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
ซึ่งเหมือนกับการใช้ range เลย
นั่นหมายความว่า xrange นั้นไม่ได้ให้ข้อมูลที่เป็นลิสต์ แต่เมื่อมันถูกเรียกใช้มันจะทำการสร้างข้อมูลตัวเลขเรียงขึ้นมาใหม่ ผลสุดท้ายจึงทำงานเหมือนเป็นลิสต์
ในการใช้งานนั้น เวลาที่สร้างตัวแปรขึ้นมานั้น xrange จะสร้างได้เร็วกว่าเพราะมันไม่ได้ทำการไล่สร้างลิสต์ขึ้นมาใหม่ในขณะนั้นเลย อีกทั้งยังทำให้ประหยัดหน่วยความจำด้วย
ลอง
import time
t0 = time.time()
a = range(1000000)
print(time.time() - t0)
ได้ผลเป็น
0.0569779872894
แต่พอลองimport time
t0 = time.time()
a = xrange(1000000)
print(time.time() - t0)
จะได้3.09944152832e-06
ซึ่งเห็นได้ชัดว่าต่างกันมาก ยิ่งจำนวนที่ทดสอบมีค่ามากความต่างก็จะยิ่งเห็นชัด
(อนึ่ง การทดสอบความเร็วนั้นในแต่ละเครื่องจะได้ผลต่างกันออกไป ขึ้นอยู่กับประสิทธิภาพของคอม)
แต่เมื่อใช้งาน xrange จึงจะทำการสร้างจำนวนขึ้นมา ดังนั้นในจังหวะนั้นมันจะทำงานช้ากว่า range เล็กน้อย
ที่ว่ามาข้างต้นนั้นคือเรื่องของไพธอน 2
ในทางกลับกันในไพธอน 3 นั้นได้ยกเลิก range แบบเดิมทิ้ง แล้วให้ range ทำงานในลักษณะเดียวกับ xrange เดิมไปแทนprint(range(10))
print(type(range(10)))
จะได้range(0, 10)
<class 'range'>
หากลองทดสอบเวลาดูimport time
t0 = time.time()
a = range(1000000)
print(time.time() - t0)
ก็จะได้
6.9141387939453125e-06
ซึ่งก็เร็วเหมือนกับการใช้ xrange ในไพธอน 2
ในขณะที่ฟังก์ชัน xrange นั้นได้หายไปจากไพธอน 3
ถ้าพิมพ์print(xrange(10))
ก็จะขึ้นมาว่า
NameError: name 'xrange' is not defined
ส่วนฟังก์ชัน range ในรูปแบบเดิมในไพธอน 2 นั้นก็ได้หายไป ไม่สามารถทำได้แล้ว
แต่หากต้องการให้ได้ลิสต์ในลักษณะแบบฟังก์ชัน range เดิมในไพธอน 2 ก็แค่ต้องใช้ฟังก์ชัน list เพื่อเปลี่ยนตอนที่สร้างขึ้นมาทันทีa = list(range(10))
แบบนี้ก็จะได้ข้อมูลออกมาเป็นลิสต์แล้ว
สรุปโดยรวมแล้วก็คือ หากใครใช้ xrange มาในไพธอน 2 ก็จะต้องเปลี่ยนมาใช้ range แทนในไพธอน 3 ซึ่งความหมายของ range ในไพธอน 3 ก็จะเหมือนกับ xrange ในไพธอน 2
ในขณะที่ หากใครที่ใช้ range มาตั้งแต่ในไพธอน 2 แล้วเปลี่ยนมาใช้ไพธอน 3 ก็ยังสามารถใช้ range ได้เหมือนเดิม เพียงแต่ชนิดข้อมูลที่ได้จะเปลี่ยนไปเท่านั้น การทำงานก็เปลี่ยนไป แต่ผลยังเหมือนเดิม
อ้างอิง