Các trình lặp Python không phải là một hasNextphương thức?
Các trình lặp Python không phải là một hasNextphương thức?
Câu trả lời:
Không, không có phương pháp như vậy. Sự kết thúc của phép lặp được chỉ định bởi một ngoại lệ. Xem tài liệu .
unnext()phương pháp để đưa phần tử đầu tiên trở lại sau khi tôi đã kiểm tra xem nó có tồn tại không bằng cách gọi next().
yieldhay không). Tất nhiên, không khó để viết một bộ chuyển đổi lưu trữ kết quả next()và cung cấp has_next()và move_next().
hasNext()phương thức (để tạo, bộ đệm và trả về giá trị true khi thành công hoặc trả về false khi thất bại). Sau đó, cả hai hasNext()và next()sẽ phụ thuộc vào một getNext()phương thức cơ bản phổ biến và mục được lưu trữ. Tôi thực sự không hiểu tại sao next()không nên ở trong thư viện tiêu chuẩn nếu việc triển khai bộ điều hợp cung cấp nó rất dễ dàng.
next()và hasNext()phương pháp nào, không chỉ là thư viện Python giả định). Vì vậy, có, next()và hasNext()trở nên khó khăn nếu nội dung của luồng được quét phụ thuộc vào thời điểm các phần tử được đọc.
Có một sự thay thế cho StopIterationbằng cách sử dụng next(iterator, default_value).
Ví dụ:
>>> a = iter('hi')
>>> print next(a, None)
h
>>> print next(a, None)
i
>>> print next(a, None)
None
Vì vậy, bạn có thể phát hiện Nonehoặc giá trị được chỉ định trước khác cho phần cuối của trình vòng lặp nếu bạn không muốn cách ngoại lệ.
sentinel = object()và next(iterator, sentinel)và thử nghiệm với is.
unittest.mock.sentinelđối tượng tích hợp cho phép bạn viết một bản next(a, sentinel.END_OF_ITERATION)if next(...) == sentinel.END_OF_ITERATION
Nếu bạn thực sự cần một has-nextchức năng (vì bạn chỉ cần sao chép một cách trung thực một thuật toán từ một triển khai tham chiếu trong Java, hoặc bởi vì bạn đang viết một nguyên mẫu sẽ dễ dàng được sao chép sang Java khi hoàn thành), thật dễ dàng để có được nó với một lớp bao bọc nhỏ. Ví dụ:
class hn_wrapper(object):
def __init__(self, it):
self.it = iter(it)
self._hasnext = None
def __iter__(self): return self
def next(self):
if self._hasnext:
result = self._thenext
else:
result = next(self.it)
self._hasnext = None
return result
def hasnext(self):
if self._hasnext is None:
try: self._thenext = next(self.it)
except StopIteration: self._hasnext = False
else: self._hasnext = True
return self._hasnext
bây giờ một cái gì đó như
x = hn_wrapper('ciao')
while x.hasnext(): print next(x)
phát ra
c
i
a
o
theo yêu cầu.
Lưu ý rằng việc sử dụng next(sel.it)dưới dạng tích hợp yêu cầu Python 2.6 trở lên; nếu bạn đang sử dụng phiên bản Python cũ hơn, hãy sử dụng self.it.next()thay thế (và tương tự như next(x)trong cách sử dụng ví dụ). [[Bạn có thể nghĩ rằng ghi chú này là dư thừa, vì Python 2.6 đã tồn tại hơn một năm nay - nhưng thường xuyên hơn là khi tôi sử dụng các tính năng của Python 2.6 trong một phản hồi, một số người bình luận hoặc người khác cảm thấy bị ràng buộc phải chỉ ra rằng chúng là 2,6 tính năng, do đó tôi đang cố gắng kiểm tra các nhận xét như vậy một lần ;-)]]
has_nextphương thức. Thiết kế của Python làm cho không thể sử dụng filterđể kiểm tra xem một mảng có chứa phần tử khớp với một vị từ đã cho hay không. Sự kiêu ngạo và thiển cận của cộng đồng Python là đáng kinh ngạc.
TypeError: iter() returned non-iterator
mapvà anythay vì filter, nhưng bạn có thể sử dụng SENTINEL = object(); next(filter(predicate, arr), SENTINEL) is not SENTINELhoặc quên SENTINELvà chỉ sử dụng try: exceptvà bắt StopIteration.
Ngoài tất cả các đề cập đến StopIteration, vòng lặp "for" của Python chỉ đơn giản là làm những gì bạn muốn:
>>> it = iter("hello")
>>> for i in it:
... print i
...
h
e
l
l
o
Hãy thử phương thức __length_hint __ () từ bất kỳ đối tượng lặp nào:
iter(...).__length_hint__() > 0
__init__và __main__không? Imho, đó là một chút lộn xộn cho dù bạn cố gắng biện minh cho nó.
hasNextphần nào chuyển thành StopIterationngoại lệ, ví dụ:
>>> it = iter("hello")
>>> it.next()
'h'
>>> it.next()
'e'
>>> it.next()
'l'
>>> it.next()
'l'
>>> it.next()
'o'
>>> it.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
StopIterationtài liệu: http://docs.python.org/l Library / exceptions.html # exceptions.StopIterationKhông. Khái niệm tương tự nhất rất có thể là ngoại lệ StopIteration.
Tôi tin rằng python chỉ có next () và theo tài liệu, nó ném một ngoại lệ là không có nhiều yếu tố nữa.
http://docs.python.org/l Library / stdtypes.html#iterator-types
Trường hợp sử dụng dẫn tôi tìm kiếm này là như sau
def setfrom(self,f):
"""Set from iterable f"""
fi = iter(f)
for i in range(self.n):
try:
x = next(fi)
except StopIteration:
fi = iter(f)
x = next(fi)
self.a[i] = x
nơi hasnext () có sẵn, người ta có thể làm
def setfrom(self,f):
"""Set from iterable f"""
fi = iter(f)
for i in range(self.n):
if not hasnext(fi):
fi = iter(f) # restart
self.a[i] = next(fi)
mà với tôi là sạch hơn. Rõ ràng là bạn có thể giải quyết các vấn đề bằng cách xác định các lớp tiện ích, nhưng điều xảy ra là bạn có một cách giải quyết hai cách giải quyết khác nhau gần như tương đương nhau với các quirks của chúng và nếu bạn muốn sử dụng lại mã sử dụng các cách giải quyết khác nhau, bạn phải có nhiều ứng dụng gần tương đương trong một ứng dụng của bạn hoặc đi xung quanh chọn và viết lại mã để sử dụng cùng một cách tiếp cận. Câu châm ngôn 'làm một lần và làm tốt' thất bại nặng nề.
Hơn nữa, bản thân trình lặp cần phải có kiểm tra 'hasnext' nội bộ để chạy để xem liệu nó có cần đưa ra một ngoại lệ hay không. Kiểm tra nội bộ này sau đó được ẩn để nó cần được kiểm tra bằng cách thử lấy một vật phẩm, bắt ngoại lệ và chạy trình xử lý nếu bị ném. Đây là IMO ẩn không cần thiết.
Cách đề xuất là StopIteration . Vui lòng xem ví dụ về Fibonacci từ hướng dẫn
#!usr/bin/python3
import sys
def fibonacci(n): #generator function
a, b, counter = 0, 1, 0
while True:
if (counter > n):
return
yield a
a, b = b, a + b
counter += 1
f = fibonacci(5) #f is iterator object
while True:
try:
print (next(f), end=" ")
except StopIteration:
sys.exit()
Cách tôi giải quyết vấn đề của mình là giữ số lượng đối tượng lặp đi lặp lại cho đến nay. Tôi muốn lặp lại một tập hợp bằng cách sử dụng các cuộc gọi đến một phương thức cá thể. Vì tôi biết độ dài của tập hợp và số lượng vật phẩm được tính cho đến nay, tôi thực sự có một hasNextphương pháp.
Một phiên bản đơn giản của mã của tôi:
class Iterator:
# s is a string, say
def __init__(self, s):
self.s = set(list(s))
self.done = False
self.iter = iter(s)
self.charCount = 0
def next(self):
if self.done:
return None
self.char = next(self.iter)
self.charCount += 1
self.done = (self.charCount < len(self.s))
return self.char
def hasMore(self):
return not self.done
Tất nhiên, ví dụ là một món đồ chơi, nhưng bạn có ý tưởng. Điều này sẽ không hoạt động trong trường hợp không có cách nào để có được độ dài của vòng lặp, như máy phát điện, v.v.