>>> range(1,11)
ให้คุณ
[1,2,3,4,5,6,7,8,9,10]
ทำไมไม่ 1-11
พวกเขาตัดสินใจที่จะทำอย่างนั้นแบบสุ่มหรือมีคุณค่าที่ฉันไม่เห็นหรือเปล่า
range()
ทำให้รู้สึกบ่อยขึ้น
>>> range(1,11)
ให้คุณ
[1,2,3,4,5,6,7,8,9,10]
ทำไมไม่ 1-11
พวกเขาตัดสินใจที่จะทำอย่างนั้นแบบสุ่มหรือมีคุณค่าที่ฉันไม่เห็นหรือเปล่า
range()
ทำให้รู้สึกบ่อยขึ้น
คำตอบ:
เพราะมันเป็นเรื่องปกติมากขึ้นที่จะเรียกrange(0, 10)
ซึ่งผลตอบแทน[0,1,2,3,4,5,6,7,8,9]
ที่มีองค์ประกอบ 10 len(range(0, 10))
ซึ่งเท่ากับ จำไว้ว่าโปรแกรมเมอร์ต้องการดัชนีแบบ 0
นอกจากนี้ให้พิจารณาข้อมูลโค้ดทั่วไปต่อไปนี้:
for i in range(len(li)):
pass
คุณจะเห็นว่าถ้าrange()
ไปถึงlen(li)
ที่ว่านี้จะเป็นปัญหาได้หรือไม่ โปรแกรมเมอร์จะต้องชัดเจนลบ 1 นี้ยังเป็นไปตามแนวโน้มทั่วไปของโปรแกรมเมอร์พอใจมากกว่าfor(int i = 0; i < 10; i++)
for(int i = 0; i <= 9; i++)
หากคุณกำลังโทรหาช่วงที่เริ่มต้น 1 บ่อยครั้งคุณอาจต้องการกำหนดฟังก์ชั่นของคุณเอง:
>>> def range1(start, end):
... return range(start, end+1)
...
>>> range1(1, 10)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
range(start, count)
ไม่?
range(10)
range(0, 10)
range1
1
for i in range(len(li)):
ค่อนข้างเป็นปฏิปักษ์ enumerate
หนึ่งควรใช้
แม้ว่าจะมีคำอธิบายอัลกอริทึมที่มีประโยชน์อยู่ที่นี่ แต่ฉันคิดว่ามันอาจช่วยเพิ่มเหตุผล 'ชีวิตจริง' ที่เรียบง่ายว่าทำไมมันถึงทำงานได้ด้วยวิธีนี้ซึ่งฉันพบว่ามีประโยชน์เมื่อแนะนำเรื่องนี้ให้กับผู้มาใหม่
ด้วยความสับสนเช่น 'ช่วง (1,10)' อาจเกิดขึ้นจากการคิดว่าพารามิเตอร์คู่หมายถึง
เป็นจริงเริ่มและ "หยุด"
ทีนี้ถ้ามันเป็นค่า "จบ" แล้วใช่คุณอาจคาดหวังว่าจำนวนนั้นจะถูกรวมเป็นรายการสุดท้ายในลำดับ แต่มันไม่ใช่ "ตอนจบ"
คนอื่นเรียกพารามิเตอร์นั้นว่า "นับ" โดยไม่ได้ตั้งใจเพราะถ้าคุณใช้ 'range (n)' เท่านั้นแน่นอนว่ามันทำซ้ำ 'n' ครั้ง ตรรกะนี้ผิดพลาดเมื่อคุณเพิ่มพารามิเตอร์เริ่มต้น
ดังนั้นจุดสำคัญคือการจำชื่อของมัน: " หยุด " ซึ่งหมายความว่าเป็นจุดที่เมื่อถึงจุดซ้ำจะหยุดทันที ไม่ใช่หลังจากนั้น
ดังนั้นในขณะที่ "เริ่มต้น" จะแสดงถึงค่าแรกที่จะรวมในการเข้าถึง "หยุด" มูลค่ามัน 'แบ่ง' มากกว่าดำเนินการต่อเพื่อดำเนินการ 'หนึ่งเช่นกัน' ก่อนที่จะหยุด
สิ่งหนึ่งที่ฉันเคยอธิบายเรื่องนี้กับเด็ก ๆ ก็คือมันน่าขันมากกว่าพฤติกรรมของเด็ก! มันไม่หยุดหลังจากที่ควรจะ - มันหยุดทันทีโดยไม่ทำในสิ่งที่มันทำ (พวกเขาได้รับสิ่งนี้;)
การเปรียบเทียบอื่น - เมื่อคุณขับรถคุณจะไม่ผ่านป้ายหยุด / ให้ผลตอบแทน / 'หลีกทาง' และจบลงด้วยการนั่งข้างใดข้างหนึ่งหรือข้างหลังรถของคุณ ในทางเทคนิคคุณยังไม่ถึงเมื่อคุณหยุด ไม่รวมอยู่ใน 'สิ่งที่คุณทำในการเดินทาง'
ฉันหวังว่าสิ่งเหล่านี้จะช่วยอธิบาย Pythonitos / Pythonitas!
ช่วงพิเศษมีประโยชน์บางอย่าง:
สำหรับสิ่งหนึ่งในแต่ละรายการเป็นดัชนีที่ถูกต้องสำหรับรายการของความยาวrange(0,n)
n
นอกจากนี้ยังrange(0,n)
มีความยาวn
ไม่n+1
รวมช่วงที่จะ
มันทำงานได้ดีร่วมกับการจัดทำดัชนี zero-based len()
และ ตัวอย่างเช่นหากคุณมี 10 รายการในรายการx
พวกเขาจะมีหมายเลข 0-9 range(len(x))
ให้คุณ 0-9
แน่นอนคนจะบอกคุณก็มากขึ้น Pythonic ที่จะทำfor item in x
หรือมากกว่าfor index, item in enumerate(x)
for i in range(len(x))
การแบ่งส่วนทำงานในลักษณะเดียวกัน: foo[1:4]
เป็นรายการที่ 1-3 ของfoo
(โปรดจำไว้ว่ารายการที่ 1 เป็นรายการที่สองเนื่องจากการทำดัชนีแบบ zero-based) เพื่อความมั่นคงพวกเขาทั้งคู่ควรทำงานในลักษณะเดียวกัน
ฉันคิดว่ามันเป็น: "หมายเลขแรกที่คุณต้องการตามด้วยหมายเลขแรกที่คุณไม่ต้องการ" ถ้าคุณต้องการที่ 1-10 จำนวนแรกที่คุณไม่ต้องการเป็น 11 range(1, 11)
ดังนั้นจึงเป็นเรื่อง
ถ้ามันจะกลายเป็นความยุ่งยากในการประยุกต์ใช้โดยเฉพาะอย่างยิ่งก็พอที่ง่ายต่อการเขียนฟังก์ชั่นช่วยตัวน้อยที่เพิ่ม 1 range()
ถึงดัชนีสิ้นสุดและบริการโทร
w = 'abc'; w[:] == w[0:len(w)]; w[:-1] == w[0:len(w)-1];
def full_range(start,stop): return range(start,stop+1) ## helper function
for index, item in enumerate(x)
เพื่อหลีกเลี่ยงความสับสน
นอกจากนี้ยังมีประโยชน์สำหรับการแยกช่วง range(a,b)
สามารถแบ่งออกเป็นrange(a, x)
และrange(x, b)
ในขณะที่มีช่วงรวมคุณจะเขียนอย่างใดอย่างหนึ่งหรือx-1
x+1
ในขณะที่คุณไม่จำเป็นต้องแยกช่วงคุณมักจะแยกรายการบ่อย ๆ ซึ่งเป็นหนึ่งในเหตุผลที่แบ่งรายการl[a:b]
มีองค์ประกอบ a-th แต่ไม่ใช่ b-th แล้วrange
มีคุณสมบัติเดียวกันทำให้สอดคล้องกัน
ความยาวของช่วงคือค่าสูงสุดลบค่าต่ำสุด
มันคล้ายกับสิ่งที่ชอบมาก:
for (var i = 1; i < 11; i++) {
//i goes from 1 to 10 in here
}
ในภาษา C-style
ยังชอบช่วงของทับทิม:
1...11 #this is a range from 1 to 10
อย่างไรก็ตาม Ruby ยอมรับว่าหลายครั้งที่คุณต้องการรวมค่าเทอร์มินัลและเสนอไวยากรณ์ทางเลือก:
1..10 #this is also a range from 1 to 10
1..10
เทียบ1...10
เป็นเรื่องยากที่จะแยกแยะความแตกต่างระหว่างการอ่านรหัส!
โดยทั่วไปแล้วในไพ ธ อนrange(n)
ซ้ำn
ครั้งซึ่งเป็นลักษณะพิเศษที่เป็นเหตุให้มันไม่ให้ค่าสุดท้ายเมื่อมันถูกพิมพ์เราสามารถสร้างฟังก์ชั่นที่ให้มูลค่ารวมมันหมายความว่ามันจะพิมพ์ค่าสุดท้ายที่กล่าวถึงในช่วง
def main():
for i in inclusive_range(25):
print(i, sep=" ")
def inclusive_range(*args):
numargs = len(args)
if numargs == 0:
raise TypeError("you need to write at least a value")
elif numargs == 1:
stop = args[0]
start = 0
step = 1
elif numargs == 2:
(start, stop) = args
step = 1
elif numargs == 3:
(start, stop, step) = args
else:
raise TypeError("Inclusive range was expected at most 3 arguments,got {}".format(numargs))
i = start
while i <= stop:
yield i
i += step
if __name__ == "__main__":
main()
พิจารณารหัส
for i in range(10):
print "You'll see this 10 times", i
แนวคิดก็คือคุณจะได้รับรายการความยาวy-x
ซึ่งคุณสามารถทำซ้ำได้
อ่านเพิ่มเติมเกี่ยวกับเอกสารของไพ ธ อน - พวกมันพิจารณาการวนซ้ำแบบวนซ้ำโดยใช้ไฟล์หลัก
สะดวกกว่าที่จะให้เหตุผลในหลาย ๆ กรณี
โดยทั่วไปเราอาจคิดว่าช่วงเป็นช่วงเวลาระหว่างและstart
end
ถ้าความยาวของช่วงเวลาระหว่างพวกเขาคือstart <= end
end - start
หากlen
กำหนดตามความยาวจริงคุณจะต้อง:
len(range(start, end)) == start - end
อย่างไรก็ตามเรานับจำนวนเต็มที่รวมอยู่ในช่วงแทนที่จะวัดความยาวของช่วงเวลา เพื่อให้คุณสมบัติดังกล่าวเป็นจริงเราควรรวมหนึ่งในจุดสิ้นสุดและแยกออกจากกัน
การเพิ่มstep
พารามิเตอร์นั้นเหมือนกับการแนะนำหน่วยของความยาว ในกรณีนี้คุณคาดหวัง
len(range(start, end, step)) == (start - end) / step
สำหรับความยาว ในการรับการนับคุณเพียงแค่ใช้การหารจำนวนเต็ม