testList.remove[not "1"]

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
Graf_Dracula
User
Beiträge: 20
Registriert: Donnerstag 17. Februar 2011, 16:05

Hallöle,

ich habe eine liste mit ca. 1600 Einträgen (Ordnernamen), wovon ich alle diejenigen löschen möchte, die einen bestimmten String NICHT enthalten.

Der folgende Code funktioniert natürlich leider nicht:

Code: Alles auswählen

testList = ["1", "2", "3", "1", "2", "3", "1", "2", "3", "1", "2", "3", "1", "2", "3"]

testList.remove[not "1"]
Mir fallen 2 Möglickeiten ein, Beide benötigen mir aber zu lange, wodurch es immer so aussieht, als wenn das Program für 7sec stecken geblieben ist, denn genau so lange dauert es (bei Beiden Versionen), bis die Elemente aussortiert sind:
Ich hab natürlich auf C:\ keine 1600 Ordner ... ist nur für hier, damit der Code funktioniert. Der Ordner, den ich allerdings durchsuche HAT ca. 1650 Ordner.

Version 1:

Code: Alles auswählen

import os
sourceFolder="C:\\"
mask = "xyz"

rootElements  = os.listdir(sourceFolder)

rootElements2 = []
for i in rootElements:
    if (i.find(mask) >= 0):
        rootElements2.append(i)
Version 2:

Code: Alles auswählen

import os, re
sourceFolder="C:\\"
mask = "x"

rootElements  = os.listdir(sourceFolder)
pattern = re.compile(mask)

rootElements2 = []
for i in rootElements:
    if pattern.search(i):
        rootElements2.append(i)
Gibts also eine einfache uns vor allem schnelle Möglichkeit aus einer riesigen Liste unwanted Einträge zu entfernen?
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Da der Graf von enthalten schreibt, ist

Code: Alles auswählen

l = ['10', '20', '10', '30', '04', '01']
m = [e for e in l if '1' not in e]
wohl zielführender ...

Edit: Eben war hier doch noch ein anderer Post?!
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

Wie wäre es mit der alternative, die ungewollten Pfade erst garnicht einzulesen:

Code: Alles auswählen

import glob
glob.glob('*1*')
Graf_Dracula
User
Beiträge: 20
Registriert: Donnerstag 17. Februar 2011, 16:05

gkuhl hat geschrieben:Wie wäre es mit der alternative, die ungewollten Pfade erst garnicht einzulesen:

Code: Alles auswählen

import glob
glob.glob('*1*')
Ist mir auch grad während dessen schon eingefallen ... es funzt und geht rasend schnell ... von vorher 7sec auf jetzt nicht messbare <1sec.

Code: Alles auswählen

import os, glob
sourceFolder="C:\\"
mask = "x"

rootElements=[]
if not (mask == "..."):
     for i in glob.glob(sourceFolder + os.sep + "*" + pathMask + "*"):
          rootElements.append(i)
else:
     for i in glob.glob(sourceFolder + os.sep + "*"):
          rootElements.append(i)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Du kannst die überflüssigen for-Schleifen einsparen, wenn du einfach

Code: Alles auswählen

root_elements = list(glob.glob(...))
verwendest. Pfade solltest du mit `os.path.join` zusammensetzen und dich bei Bezeichnern an PEP 8 halten. Statt `rootElements` also zum Beispiel besser `root_elements`.

Und vielleicht noch ein Alternative zu frabrons Lösung:

Code: Alles auswählen

>>> data = ["1", "2", "3", "1", "2", "3", "1", "2", "3", "1", "2", "3", "1", "2", "3"]
>>> filter("1".__ne__, data)
['2', '3', '2', '3', '2', '3', '2', '3', '2', '3']
Vorher mit `glob` zu filtern ist natürilch immer noch einfacher und eleganter.

Sebastian
Das Leben ist wie ein Tennisball.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

[quote="Graf_Dracula"]Du erstellst aus einer Liste eine identische Liste. Die Version ohne Umwege sieht so aus:

Code: Alles auswählen

rootElements=[]
if not (mask == "..."):
     root_elements = glob.glob(sourceFolder + os.sep + "*" + pathMask + "*"):
else:
     root_elements = glob.glob(sourceFolder + os.sep + "*"):
Den Namen rootElements habe ich noch PEP-8 konform angepasst.
BlackJack

@Graf_Dracula: Das erstellen einer neuen Liste ohne die unerwünschten Elemente wäre ohne `glob()` der richtige Weg gewesen und ich kann mir nicht vorstellen, dass das gezeigte wirklich 7 Sekunden gedauert haben soll. Es sei denn Du hast das auf einem *sehr* langsamen Rechner oder mit *sehr* vielen Elementen in der Liste gemacht.
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

Wenn man als Vorgabewert für ``mask`` "*" verwendet statt "...", kann man es auch wie folgt schreiben:

Code: Alles auswählen

source_folder = 'C:\\'
glob.glob(os.path.join(source_folder, '*%s*' % mask))
Ich wüde ``not (mask == "...")`` auch als ``mask != "..."`` schreiben.
Antworten