wie kriege ich alle vorkommen von 'sub' in einer Liste?

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
jörg

Sonntag 19. Dezember 2004, 01:31

Hallo,
mal wieder ne newbie-Frage, wahrscheinlich gibt's ne schicke Lösung a la 'Liste[0:max].magic(foo)[23]', ich frag mal einfach... 8)

Also, ich bräuchte eine funktion die eine Liste zurückgibt mit den indices
aller vorkommnisse eines Elements in einer Liste, z.B. ich habe eine
wilde Liste mit Namen und will alle Stellen an denen 'Meier' steht.
Ich hab da mal folgendes vorbereitet:

Code: Alles auswählen

tstlist = [1,2,17,3,4,5,6,7,8,2,9, 10, 3,11,12,13,14, 2,15,16,17, 7]

def ListFind(List, sub):
    TmpList = []
    carryon = 1
    index = -1
    while carryon:
        try:
            index = List.index(sub, index+1)
            TmpList.append(index)
        except ValueError:
            carryon = 0
    return TmpList

print ListFind(tstlist, 2)

Das klappt auch soweit, nur hab ich irgendwie ein schlechtes Gefühl
dabei und folgende Fragen:
- gibt es womöglich in Python schon eine funktion genau dafür?
(-> hab mir schon in der doku die hacken abgesucht aber nix efunden...)
- wenn nicht, kann man das eleganter lösen?
- und wenn immer noch nicht, wie würde man es machen das es zu
benutzen ist wie list.index(), also zB 'tstlist.ListFind(17)' ...hat das mit
Subclasses zu tun? aber wenn, dann wie?

wieder mal ein dickes 'Danke',
Joerg

Edit (Leonidas): Code in Python Tags gesetzt.
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Sonntag 19. Dezember 2004, 01:38

Also wenn ich dich richtig verstanden habe würde ich es so machen:

Code: Alles auswählen


res = [index for index,value in enumerate(werteListe) if value == 2]

Weiss aber auch nicht, ob es die einfachste oder schnellste Version ist.


gruss Rayo
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Sonntag 19. Dezember 2004, 01:45

Hi joerg,

Code: Alles auswählen

def list_find(List, sub):
    return [i for i, value in enumerate(List) if value == sub]
enumerate erzeugt einen Iterator, der die Werte aus einem Iterable (Liste, Tuple, String ...) als Index/Wert-Paare zurückgibt


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Sonntag 19. Dezember 2004, 01:47

da war der Rayo etwas schneller :)
dafür hab ich das in eine Funktion gepackt ;)


Dookie
[code]#!/usr/bin/env python
import this[/code]
Gast

Sonntag 19. Dezember 2004, 02:09

Boah,
das waren mal fixe antworten, und das um zwei des nachts!
Nachdem sich das auch alles sehr plausibel anhört bin ich glaub ich zufrieden
damit und frag nicht weiter wg. dem tstlist.findlist(17)... sondern guck mir
erst mal enumerate in der doku an... :)

Gruss & Dank,
Jörg
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Sonntag 19. Dezember 2004, 02:47

Hi joerg,

kannst dir enumerate auch in der Pythonconsole anschaun:

Code: Alles auswählen

 >>> print list(enumerate(tstlist))
[(0, 1), (1, 2), (2, 17), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 2),
 (10, 9), (11, 10), (12, 3), (13, 11), (14, 12), (15, 13), (16, 14), (17, 2),
 (18, 15), (19, 16), (20, 17), (21, 7)]
Gruß

Dookie
Zuletzt geändert von Dookie am Sonntag 19. Dezember 2004, 03:50, insgesamt 1-mal geändert.
[code]#!/usr/bin/env python
import this[/code]
jörg

Sonntag 19. Dezember 2004, 03:08

Ha,
allerdings hab ich grad festgestellt dass zB das auszählen aller lowercases
in einem 2k-textfile mit meiner def 5 sek dauert, mit dem enumerate aber 40...

siehe:

Code: Alles auswählen

import string
import time

filename = "c:/filetest/email.txt"

myfile = open(filename, "rb")

tstlist = myfile.read()

#def ListFind(List, sub):
#    TmpList = []
#    carryon = 1
#    index = -1
#    while carryon:
#        try:
#            index = List.index(sub, index+1)
#            TmpList.append(index)
#        except ValueError:
#            carryon = 0
#    return TmpList

def ListFind(List, sub):
    return [i for i, value in enumerate(List) if value == sub] 

a = time.time()

for i in list(string.ascii_lowercase):
    b = ListFind(tstlist,i)

print time.time() - a
was nun?

Jörg
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Sonntag 19. Dezember 2004, 11:16

Hi

Dann erlaub ich mir mal die Frage warum du das willst? oder für was du das brauchst. Vielleicht gibts ja einen ganz anderen Ansatz.

Ich tüftel mal ein wenig weiter.


Gruss
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Sonntag 19. Dezember 2004, 13:36

Hi auch,

is, nach etwas überlegen, klar das die LC länger braucht, da wird auch jeder Eintrag der Liste in Python verglichen, im Gegensatz zu deiner Funktion, die von gefundenem Eintrag zum nächsten springt und der Vergleich erfolgt in der index-Methode, die ja in C implementiert ist.
Die LC hat aber den Vorteil, daß du auch eine Regular Expression verwenden kannst.


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Antworten