´in´ für Teil-Listen (wie beim String)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich habe mal eine bespielhafte Implementierung in C auf den Python-Bugtracker gesetzt. Es kamen auch schon ein paar Rückmeldungen. Der Tenor ist anscheinend, dass man die Idee grundsätzlich nicht schlecht findet, aber sich nicht sicher ist, ob dies Teil der Standardbibliothek werden soll. Eine endgültige Entscheidung steht aber wohl noch aus. Für Interessierte: http://bugs.python.org/issue25898
Üpsilon
User
Beiträge: 222
Registriert: Samstag 15. September 2012, 19:23

boah, da hab ich ja was losgetreten :O Danke!
Meine Lösung sieht i.wie so aus (hab es grade nicht dabei):

Code: Alles auswählen

def ist_teilliste(kleine_liste, grosse_liste):
    if len(kleine_liste) > len(grosse_liste): return False
    if grosse_liste[:len(kleine_liste)] == kleine_liste: return True
    return ist_teilliste(kleine_liste[1:], grosse_liste)
... Unglaubliche Effizienz durch Rekursion ...
PS: Die angebotene Summe ist beachtlich.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Hier mal aus Spaß an der Freude eine Iterator-basierte Umsetzung:

Code: Alles auswählen

#!/usr/bin/env python3

from collections import deque
from itertools import chain, islice

def dropuntil(iterable, needle):
    """
    Advance `iterable` until a sequence with all items of `needle` (with
    respect to their order) is found. Then yield all remaining items
    starting with the first item of `needle`. Yield nothing if `iterable`
    does not contain the given needle.
    """
    iterator = iter(iterable)
    window = deque(maxlen=len(needle))
    window.extend(islice(iterator, len(needle)))
    if len(window) == len(needle):
        while any(a != b for a, b in zip(window, needle)):
            try:
                window.append(next(iterator))
            except StopIteration:
                return
        yield from chain(window, iterator)

def main():
    print(list(dropuntil([1,2,9,3,4,3,5,2,3,4,2,3], [2,3])))
    print(list(dropuntil([1,2,9,3,4,3,5,2,3,4,2,3], [8,9])))
    print(''.join(dropuntil('xxxhamyyyspamzzzeggs', 'spam')))

if __name__ == '__main__':
    main()
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Hier nochmal mit `map` anstelle der Generator Comprehension zur Performancesteigerung:
http://pastebin.com/LUYUi5Zk
BlackJack

Ich würde es ja als `dropwhile()` implementieren. Die `needle` hat der Aufrufer ja schon, wenn er die vor dem Ergebnis haben möchte, kann er den `chain()`-Aufruf selber machen. Wenn er die `needle`-Daten dagegen nicht braucht, dann macht die Funktion erst ein `chain()` was der Aufrufer mit einem `islice()` wieder ”rückgängig” machen muss, also zwei Iteratorindirektionen zusätzlich.
Antworten