반복기가 적어도 하나의 요소를 산출하는지 확인하기 위한 원라이너?
현재 이 작업을 수행하고 있습니다.
try:
something = next(iterator)
# ...
except StopIteration:
# ...
하지만 저는 심플한 안에 넣을 수 있는 표현을 원합니다.if
진술.이 코드를 덜 서툴게 보이게 하는 내장된 것이 있습니까?저는 첫 번째 항목만 확인하면 됩니다.
if any(True for _ in iterator):
print('iterator had at least one element')
if all(False for _ in iterator):
print('iterator was empty')
하나 이상의 요소가 있는 경우 반복 가능한 항목의 첫 번째 요소가 사용됩니다.
Sentinel 값을 기본값으로 전달next()
:
sentinel = object()
if next(iterator, sentinel) is sentinel:
print('iterator was empty')
또한 반복자가 생성할 수 없는 "알고 있는" 값(응용프로그램 고려사항에 따라)을 센티널 값으로 사용할 수도 있습니다.
이것은 사실 더 깨끗하지는 않지만, 손실 없이 기능으로 패키지화하는 방법을 보여줍니다.
def has_elements(iter):
from itertools import tee
iter, any_check = tee(iter)
try:
any_check.next()
return True, iter
except StopIteration:
return False, iter
has_el, iter = has_elements(iter)
if has_el:
# not empty
이것은 실제로는 부정적인 것이 아니며, 특정한 경우에는 다음 기본값과 같은 더 나은(그러나 덜 일반적인) 해결책이 있을 수 있습니다.
first = next(iter, None)
if first:
# Do something
None은 많은 반복 가능한 요소일 수 있으므로 일반적이지 않습니다.
그렇게 하는 가장 좋은 방법은peekable
부터more_itertools
.
from more_itertools import peekable
iterator = peekable(iterator)
if iterator:
# Iterator is non-empty.
else:
# Iterator is empty.
만약 당신이 오래된 반복기에 대한 참조를 유지한다면, 그 반복기는 발전할 것입니다.당신은 그때부터 새로운 훔쳐보기 가능한 반복기를 사용해야 합니다.peekable
이전 반복기를 수정하는 유일한 코드 비트가 될 것으로 예상됩니다.
사용할 수 있는 항목:
if zip([None], iterator):
# ...
else:
# ...
하지만 코드 리더에게는 설명할 수 없는 일입니다.
다음은 어떻습니까?
In [1]: i=iter([])
In [2]: bool(next(i,False))
Out[2]: False
In [3]: i=iter([1])
In [4]: bool(next(i,False))
Out[4]: True
일반적으로 다음 항목이 있는지 확인할 수 있는 오버킬 반복기 래퍼입니다.물론 꽤 비효율적입니다.
class LookaheadIterator ():
def __init__(self, iterator):
self.__iterator = iterator
try:
self.__next = next (iterator)
self.__have_next = True
except StopIteration:
self.__have_next = False
def __iter__(self):
return self
def next (self):
if self.__have_next:
result = self.__next
try:
self.__next = next (self.__iterator)
self.__have_next = True
except StopIteration:
self.__have_next = False
return result
else:
raise StopIteration
def __nonzero__(self):
return self.__have_next
x = LookaheadIterator (iter ([]))
print bool (x)
print list (x)
x = LookaheadIterator (iter ([1, 2, 3]))
print bool (x)
print list (x)
출력:
False
[]
True
[1, 2, 3]
조금 늦었지만, 하지만...반복기를 목록으로 전환한 다음 해당 목록으로 작업할 수 있습니다.
# Create a list of objects but runs out the iterator.
l = [_ for _ in iterator]
# If the list is not empty then the iterator had elements; else it was empty.
if l :
pass # Use the elements of the list (i.e. from the iterator)
else :
pass # Iterator was empty, thus list is empty.
언급URL : https://stackoverflow.com/questions/3114252/one-liner-to-check-whether-an-iterator-yields-at-least-one-element
'bestsource' 카테고리의 다른 글
반응형의 양방향 바인딩 (0) | 2023.07.28 |
---|---|
PowerShell에서 어레이 어레이를 생성하려면 어떻게 해야 합니까? (0) | 2023.07.28 |
이벤트 로그가 이미 있는지 확인하는 방법 (0) | 2023.07.28 |
Android Emulator 오류 메시지: "PANIC: 'x86' CPU에 대한 에뮬레이터 엔진 프로그램이 없습니다." (0) | 2023.07.28 |
사전을 컨트롤러에 전달 asp.net mvc (0) | 2023.07.28 |