Die folgende Methode ist in meiner Klasse und versucht, sich selbst zu primen, bevor ihre Arbeit erledigt wird. Der Primer ist faul beim Ausführen seiner Arbeit als die Verarbeitungsschleife, die ihm folgt. In diesen beiden Schleifen wiederholen sich fünf Zeilen, und mir ist nicht klar, was der beste Weg zur Beseitigung der Wiederholung sein könnte.Gibt es eine Möglichkeit, diesen Generator zu trocknen?
Gibt es eine effektive und klare Möglichkeit, diese letzten fünf Zeilen nur einmal in der Klasse oder Methode zu schreiben?
Nachtrag
In Antwort auf die Frage, was prefix
und suffix
sind, hier ist die Deque
Klasse:
class Deque(collections.deque):
"""Deque([iterable[, maxlen]]) -> Deque instance"""
@property
def prefix(self):
"""Property allowing capture of all but last item in deque."""
item = self.pop()
value = tuple(self)
self.append(item)
return value
@property
def suffix(self):
"""Property allowing capture of all but first item in deque."""
item = self.popleft()
value = tuple(self)
self.appendleft(item)
return value
Zweite Version
Nach Berücksichtigung, was andere hatten die folgende Methode zu sagen, für Effizienz geschrieben wurde:
@classmethod
def __get_start_words(cls, iterable, n, start_words):
iterator, buffer, count = iter(iterable), Deque(maxlen=n), 0
for item, count in zip(iterator, range(n)):
buffer.append(item)
yield item
if count + 1 < n:
raise ValueError('iterable was too short to satisfy n')
start_words[buffer.prefix] += 1
try:
while True:
if buffer[0][-1] in cls.TERMINATORS:
start_words[buffer.suffix] += 1
item = next(iterator)
buffer.append(item)
yield item
except StopIteration:
pass
dritte Version
von Daniel Diese dritte Version des Verfahrens angepasst wurde ‚s interessante Antwort:
@classmethod
def __get_start_words(cls, iterable, n, start_words):
count, buffer = 0, Deque(maxlen=n)
for count, item in enumerate(iterable, 1):
yield item
buffer.append(item)
if count == n:
start_words[buffer.prefix] += 1
if count >= n and buffer[0][-1] in cls.TERMINATORS:
start_words[buffer.suffix] += 1
if count < n:
raise ValueError('iterable was too short to satisfy n')
Final Version
Diese Methode ist deutlich besser als meine erste Version - dank der Menschen, die mir hier geholfen.
@classmethod
def __get_start_words(cls, iterable, n, start_words):
buffer = Deque(maxlen=n)
for count, item in enumerate(iterable, 1):
yield item
buffer.append(item)
if count == n:
start_words[buffer.prefix] += 1
if count >= n and buffer[0][-1] in cls.TERMINATORS:
start_words[buffer.suffix] += 1
if len(buffer) < n:
raise ValueError('iterable was too short to satisfy n')
BTW, was ist 'buffer.prefix' und' buffer.suffix'? – quamrana
Ich habe mich entschieden, in der ersten Schleife eine logische Überprüfung durchzuführen, indem ich eine Ausnahme aufrufe. Wenn die Änderung die Frage ungültig macht, lösche ich sie gerne. –
wahrscheinlich eine bessere Frage für SE: codereview – Aaron