Seite 1 von 1

testList.remove[not "1"]

Verfasst: Freitag 29. Juli 2011, 08:05
von Graf_Dracula
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?

Re: testList.remove[not "1"]

Verfasst: Freitag 29. Juli 2011, 08:11
von frabron
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?!

Re: testList.remove[not "1"]

Verfasst: Freitag 29. Juli 2011, 08:22
von gkuhl
Wie wäre es mit der alternative, die ungewollten Pfade erst garnicht einzulesen:

Code: Alles auswählen

import glob
glob.glob('*1*')

Re: testList.remove[not "1"]

Verfasst: Freitag 29. Juli 2011, 09:28
von Graf_Dracula
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)

Re: testList.remove[not "1"]

Verfasst: Freitag 29. Juli 2011, 09:39
von EyDu
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

Re: testList.remove[not "1"]

Verfasst: Freitag 29. Juli 2011, 09:41
von /me
[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.

Re: testList.remove[not "1"]

Verfasst: Freitag 29. Juli 2011, 09:50
von 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.

Re: testList.remove[not "1"]

Verfasst: Freitag 29. Juli 2011, 09:52
von gkuhl
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.