2012-08-10 13 views
10

tôi có mã như thế này:Thay đổi số lần lặp lại trong một vòng lặp for

loopcount = 3 
for i in range(1, loopcount) 
    somestring = '7' 
    newcount = int(somestring) 
    loopcount = newcount 

vì vậy những gì tôi muốn là để thay đổi phạm vi của cho 'bên trong' vòng lặp.

Tôi đã viết mã này mong đợi phạm vi của vòng lặp for sẽ thay đổi thành (1,7) trong vòng lặp đầu tiên, nhưng nó không xảy ra.

Thay vào đó, bất kể số tôi đưa vào, nó chỉ chạy 2 lần. (Tôi muốn 6 lần .. trong trường hợp này)

Tôi đã kiểm tra các giá trị sử dụng in như thế này:

loopcount = 3 
    for i in range(1, loopcount) 
     print loopcount 
     somestring = '7' 
     newcount = int(somestring) 
     loopcount = newcount 
     print loopcount 
#output: 
3 
7 
7 
7 

Điều gì là sai? số đã được thay đổi.

Suy nghĩ của tôi sai ở đâu?

+0

Vâng, nó có thể thay đổi khoảng từ bên trong vòng lặp, xem câu trả lời mới bên dưới. –

Trả lời

23

Phạm vi được tạo ra dựa trên giá trị của loopcount vào thời điểm đó nó được gọi là - bất cứ điều gì xảy ra với loopcount sau đó là không liên quan. Những gì bạn có thể muốn là một câu lệnh while:

loopcount = 3 
i = 1 
while i < loopcount: 
    somestring = '7' 
    loopcount = int(somestring) 
    i += 1 

Các while kiểm tra rằng tình trạng i < loopcount là đúng, và nếu đúng, nếu chạy các báo cáo mà nó chứa. Trong trường hợp này, trên mỗi lần truyền qua vòng lặp, tôi được tăng lên 1. Khi vòng lặp đếm được đặt thành 7 lần đầu tiên, vòng lặp sẽ chạy sáu lần, với i = 1,2,3,4,5 và 6

Khi điều kiện sai, khi i = 7, vòng lặp while ngừng hoạt động.

(Tôi không biết trường hợp sử dụng thực tế của bạn là gì, nhưng bạn có thể không cần phải chỉ định số mới, vì vậy tôi đã xóa số đó).

+2

Thời gian có thể kết thúc bằng 'i + = 1' để mô phỏng gia tăng tự động khi lặp qua một dải –

+0

Cảm ơn. Nó đã thay đổi ngay bây giờ. –

+0

Tôi có nhiều mã bên trong nó nó sẽ không thay đổi kết quả nếu tôi sử dụng trong khi và i + = 1? –

9

Từ range() docstring:

phạm vi ([bắt đầu,] dừng lại [, bước]) -> danh sách các số nguyên

Return một danh sách có chứa một cấp số cộng các số nguyên. Phạm vi (i, j) trả về [i, i + 1, i + 2, ..., j-1]; bắt đầu (!) mặc định là 0. Khi bước được đưa ra, nó chỉ định mức tăng (hoặc giảm). Ví dụ, phạm vi (4) trả về [0, 1, 2, 3]. Điểm kết thúc bị bỏ qua! Đây là những chỉ số hợp lệ chính xác cho danh sách 4 yếu tố.

Vì vậy, range(1, 10), ví dụ, trả về một danh sách như: [1,2,3,4,5,6,7,8,9], vì vậy, mã của bạn được về cơ bản thực hiện:

loopcount = 3 
for i in [1, 2]: 
    somestring = '7' 
    newcount = int(somestring) 
    loopcount = newcount 

Khi for vòng lặp của bạn là "khởi tạo", danh sách này được tạo ra bởi range() .

+0

aha! tôi hiểu! nhưng sau đó làm thế nào để tôi thay đổi phạm vi 'bên trong' vòng lặp? tôi không thể làm được? –

+2

Nếu bạn cần sửa đổi giới hạn vòng lặp của mình, tôi khuyên bạn nên mã hóa nó bằng 'while', như được đề xuất bởi @ user802500. –

1

Khi chức năng range() được đánh giá trong for - vòng lặp nó tạo ra một chuỗi các giá trị (ví dụ: danh sách) sẽ được sử dụng để lặp lại.

range() sử dụng giá trị loopcount cho việc này. Tuy nhiên, khi đã tạo một chuỗi, không có gì bạn làm bên trong vòng lặp sẽ thay đổi danh sách đó, tức là ngay cả khi bạn thay đổi loopcount sau đó, danh sách gốc sẽ giữ nguyên => số lần lặp lại sẽ giữ nguyên .

Trong trường hợp của bạn:

loopcount = 3 
for i in range(1, loopcount): 

trở thành

for i in [1, 2]: 

Vì vậy, lặp vòng lặp của bạn hai lần, kể từ khi bạn có 2 print báo cáo trong vòng lặp get bạn 4 dòng đầu ra. Lưu ý rằng bạn đang in giá trị của loopcount mà ban đầu là 3, nhưng sau đó được đặt (và đặt lại) thành 7.

Nếu bạn muốn có thể thay đổi số lần lặp lại, hãy cân nhắc động bằng cách sử dụng số while-vòng thay thế. Tất nhiên bạn luôn có thể dừng/thoát bất kỳ vòng lặp nào sớm bằng cách sử dụng câu lệnh break.

Ngoài ra,

somestring = '7' 
    newcount = int(somestring) 

có thể được đơn giản hóa để chỉ

newcount = 7 
1

Có vẻ như tiền đề của bạn là bạn có số lần mặc định mà vòng lặp sẽ thực thi nhưng thỉnh thoảng điều kiện là khác nhau. Thay vào đó, bạn nên sử dụng vòng lặp while, nhưng bất kể bạn chỉ có thể làm:

if i == some_calculated_threshold: 
    break 

để bỏ vòng lặp thay thế.

+1

-1; câu hỏi ban đầu đang cố gắng tăng số lần qua vòng lặp từ 2 đến 7; làm thế nào là 'break' nghĩa vụ phải giúp đỡ? – geoffspear

0

Bạn có thể không tăng số lần lặp lại một lần phạm vi đã được thiết lập, nhưng bạn có thể thoát ra khỏi đầu, qua đó làm giảm số lần lặp:

for i in xrange(1, 7): 
    if i == 2: 
     break 
2

Để giải quyết cụ thể cho câu hỏi "Làm thế nào để tôi thay đổi giới hạn phạm vi", bạn có thể tận dụng lợi thế của send method for a generator:

def adjustable_range(start, stop=None, step=None): 
    if stop is None: 
     start, stop = 0, start 

    if step is None: step = 1 

    i = start 
    while i < stop: 
     change_bound = (yield i) 
     if change_bound is None: 
      i += step 
     else: 
      stop = change_bound 

Cách sử dụng:

myrange = adjustable_range(10) 

for i in myrange: 
    if some_condition: 
     myrange.send(20) #generator is now bounded at 20 
+2

+1, mặc dù đây không phải là trình tạo * biểu thức * - chỉ là một trình tạo. – lvc

+0

@lvc: Rất tiếc, đã chỉnh sửa. –

+0

Bạn có thể thử chạy mã của mình. Tôi đã cố gắng sửa phiên bản của bạn với phiên bản khác được đăng trên trang này. –

0

Dưới đây là triển khai hoàn chỉnh hơn chức năng adjustable_range do Joel Cornett cung cấp.

def adjustable_range(start, stop=None, step=None): 
    if not isinstance(start, int): 
     raise TypeError('start') 
    if stop is None: 
     start, stop = 0, start 
    elif not isinstance(stop, int): 
     raise TypeError('stop') 
    direction = stop - start 
    positive, negative = direction > 0, direction < 0 
    if step is None: 
     step = +1 if positive else -1 
    else: 
     if not isinstance(step, int): 
      raise TypeError('step') 
     if positive and step < 0 or negative and step > 0: 
      raise ValueError('step') 
    if direction: 
     valid = (lambda a, b: a < b) if positive else (lambda a, b: a > b) 
     while valid(start, stop): 
      message = yield start 
      if message is not None: 
       if not isinstance(message, int): 
        raise ValueError('message') 
       stop = message 
      start += step 
3

Các của vòng lặp while câu trả lời được đưa ra bởi user802500 có khả năng là giải pháp tốt nhất cho vấn đề thực tế của bạn; tuy nhiên, tôi nghĩ câu hỏi như được yêu cầu có câu trả lời thú vị và có tính hướng dẫn.

Kết quả của dãy số () là danh sách các giá trị liên tiếp. Vòng lặp for lặp qua danh sách đó cho đến khi nó cạn kiệt.

Đây là điểm chính: Bạn được phép tắt tiếng danh sách trong khi lặp lại.

>>> loopcount = 3 
>>> r = range(1, loopcount) 
>>> for i in r: 
     somestring = '7' 
     newcount = int(somestring) 
     del r[newcount:] 

Một sử dụng thực tế của tính năng này được lặp lại qua các nhiệm vụ trong một danh sách todo và cho phép một số nhiệm vụ để tạo todos mới:

for task in tasklist: 
    newtask = do(task) 
    if newtask: 
     tasklist.append(newtask) 
+0

Bí quyết tuyệt vời khi sử dụng tính năng có thể thay đổi được trong danh sách. Vì vậy, tôi đoán trong trường hợp số tiền mới lớn hơn kích thước danh sách ban đầu, thay vì sử dụng 'del' để xóa một số phần tử trong phạm vi, chúng tôi sẽ sử dụng 'nối thêm'. – ntough