2016-04-27 12 views
0
def hide(iterable): 
    for v in iterable: 
     yield v 

def strip_last(iterable,n): 
    counter = 0 
    for i in iterable: 
     counter += 1 
     if n == len(list(iterable)) - counter + 1: 
      return 
     yield i 

print(''.join([v for v in strip_last(hide('camaro'), 1)])) 

Ich versuche, eine strip_last Funktion zu definieren, die jeden Wert vom iterable mit Ausnahme der letzten n Werte erzeugen könnte, die wie folgt lautet:Python-Generator Drop bestimmte Anzahl Zeichen

camar 

aber es gibt mir nur:

c 

Was ist los damit ?? Danke!

+0

Meinst du "Camaro" [: - n] '? – TigerhawkT3

+0

ersetze 'i' durch' n': 'i == len (list (iterable)) - n:' Ich glaube auch nicht, dass du 'counter' brauchst. – ozgur

+0

FWIW, Sie beziehen sich auf 'strip_last' als' drop_last' in Ihrer 'print'-Anweisung unter –

Antwort

1

Wenn Sie die len(list(iterable)) erstellen, leeren Sie die iterable, so dass Sie keine weiteren Elemente zum Iterieren haben.

Entweder können Sie Ihre iterable mit itertools.tee für den Aufbau Ihrer Zähler kopieren oder Sie können einen einfacheren Ansatz nehmen und eine Liste innerhalb strip_last bauen und eine slice[:-n] davon iterieren.

bearbeiten: den Code hinzufügen -

def strip_last(iterable,n): 
    size, word = itertools.tee(iterable) 
    counter = len(list(size)) - n 
    while counter: 
     counter -= 1 
     yield word.next() 
+0

Ich denke, dass Sie auch intern ein Stück der Größe n (ein einfaches für Zähler erhalten 'iterator.next()' 1..n mal und die Stücke als kleinere Listen zurückgeben), die Sie daran hindern könnte, die kopieren Ganzer Iterator –

+1

Wenn Sie eine Liste erstellen, besiegen Sie den Zweck 'tee', machen Sie einfach eine Liste von Anfang an oder erhalten Sie die Größe von der iterablen wie' sum (1 für _ in Größe) 'auch eine Prüfung für negative Zähler – Copperfield

+0

@ Copperfield stimmte zu. Die Liste verwirft den ganzen Zweck, anders herum zählt man alle Elemente in der Größe, bis 'next()' eine Ausnahme auslöst, aber so oder so bekommen wir, was er will :-P –

0

für eine generische iterable Sie haben 2 Möglichkeiten:

1) Sie eine Liste Ihrer iterable zu machen und dann iterieren eine Scheibe es

2) Sie können n + 1 Anzahl der Elemente aus dem iterable die ganze Zeit halten und eins und fragen Sie nach anderen und wenn Sie nicht n + 1 Elemente haben können Sie wissen, dass Sie fertig sind

from itertools import islice #, izip 
from collections import deque 

def strip_last_v1(iterable,n): 
    it = tuple(iterable) #because tuple weight less than a list of the same size 
    stop = len(it) - n 
    if stop > 0: 
     for x in islice(it,stop): #I use islice instead of it[:-n] because the later make a copy of the tuple 
      yield x 

def strip_last_v2(iterable,n): 
    n = n+1 
    stack = deque(maxlen=n) 
    it = iter(iterable) 
    for e,_ in zip(it,range(n)): #izip and xrange for python 2 
     stack.append(e) 
    while len(stack) == n: 
     yield stack.popleft() 
     stack.append(next(it))