Các trình lặp Python không phải là một hasNext
phương thức?
Các trình lặp Python không phải là một hasNext
phươ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()
.
yield
hay 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 StopIteration
bằ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 None
hoặ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-next
chứ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_next
phươ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
map
và any
thay vì filter
, nhưng bạn có thể sử dụng SENTINEL = object(); next(filter(predicate, arr), SENTINEL) is not SENTINEL
hoặc quên SENTINEL
và chỉ sử dụng try: except
và 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ó.
hasNext
phần nào chuyển thành StopIteration
ngoạ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
StopIteration
tà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 hasNext
phươ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.