Problem mit nested loop

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
virginiawalker
User
Beiträge: 6
Registriert: Donnerstag 21. Januar 2010, 09:12
Wohnort: Ulm

Hallo allerseits,

Hier mein Problem:
Die erste Schleife des Programms ließt die Datei "tmp_crypt2.tmp" aus, die genau aus 3 Zeilen besteht.
Inhalt:
VG00-LV00
VG00-LV01
VG00-LV04

Die zweite Schleife ließt die Datei "crypty" aus, die ebenfalls aus 3 Zeilen besteht.
Inhalt:
VG00/LV03
VG00-LV00
VG00-LV01

Unten das Problem und der Output:

Code: Alles auswählen

#!/usr/bin/env python
import os,sys

tmpR2=open('/tmp/tmp_crypt2.tmp', 'r')  # erste Datei
CTAB=open('/tmp/crypty','r')                  # zweite Datei
times=0     # zum zählen der 1.Schleife
ctimes=0   # zum zählen der 2.Schleife

for cline in tmpR2:              # für jede Zeile in Datei 1, 
        print('times: %s' %times)  # zeig den 1.Zähler
        times+=1                           # zähl eins hoch
        for T in CTAB:                   # für jede Zeile in Datei 2,
                T=T.strip()                 # mach die Leerzeilen weg
                print('C: %s' %T)      # geb die akt.Zeile aus Datei 2 aus
                ctimes+=1                 # zähl eins hoch
                print('ctimes: %s' %ctimes)   # zeig den 2.Zähler
        print '---------------------'        # Trennstrich
Output:
times: 0
C: VG00/LV03
ctimes: 1
C: VG00-LV00
ctimes: 2
C: VG00-LV01
ctimes: 3
---------------------
times: 1
---------------------
times: 2
---------------------

Problem/Ziel:
Für jede Zeile der ersten Datei soll die ganze 2. Datei durchforstet werden und später
suchen, ob der String der ersten Datei irgendwo in der 2. Datei schon vorhanden ist.
Das Problem sieht man am Output. Die erste Schleife läuft einmal durch, dann läuft die 2. Schleife einmal durch, dann läuft die erste Schleife noch 2 mal weiter OHNE die 2. Schleife.
Warum läuft also die 2. Schleife nur beim ERSTEN Mal durch ?

Wenn ich in der 2. Schleife

Code: Alles auswählen

for T in range(3):
anstatt

Code: Alles auswählen

for T in CTAB:
setze, läuft es so durch wie es soll. 3x3
Also so:

times: 0
ctimes: 1
ctimes: 2
ctimes: 3
---------------------
times: 1
ctimes: 4
ctimes: 5
ctimes: 6
---------------------
times: 2
ctimes: 7
ctimes: 8
ctimes: 9
--------------------

Ziel: der code ist ein Ausschnitt eines größeren Projekts. Ich lass das Prog. rausfinden, welche luks-devices gemountet sind und ziehe von dieser Menge all jene ab, die bereits in /etc/crypttab drin stehen, denn die will man meist nicht zur Laufzeit aushebeln...

Kann mir irgendjemand hier helfen ?

Danke schonmal.
Zuletzt geändert von virginiawalker am Donnerstag 21. Januar 2010, 12:18, insgesamt 1-mal geändert.
Never miss a good opportunity to shut up ;-)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Wie wäre es mit sowas:

Code: Alles auswählen

from __future__ import with_statement

with open('two', 'r') as ctab_file:
    ctab = frozenset(line.strip() for line in ctab_file)

with open('one', 'r') as tmp_file:
    ttab = frozenset(line.strip() for line in tmp_file)

print ttab.intersection(ctab)
Dein Problem ist, dass die zweite Datei beim zweiten Durchlauf schon ganz am Ende ist, also müsstest du entweder die Datei neu öffnen oder den Dateizeiger nach vorne setzen. Oder einfach die Datei komplett einlesen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
virginiawalker
User
Beiträge: 6
Registriert: Donnerstag 21. Januar 2010, 09:12
Wohnort: Ulm

Danke.
Die Methode mit "intersection" funktioniert in diesem Fall gut.

Das ergibt den output:
frozenset(['VG00-LV01', 'VG00-LV00'])
Also die übereinstimmenden Elemente.

Aber: Wenn ich von der echten /etc/crypttab lese, funktioniert es leider
nicht mehr.

Hier meine crypttab:
-------------------------
# <target name> <source device> <key file> <options>

swap /dev/mapper/VG00/LV03 /dev/urandom cipher=blowfish,size=256,hash=sha256,swap
home /dev/mapper/VG00-LV00 none luks
var /dev/mapper/VG00-LV01 none luks
-------------------------

Und hier die Elemente die er darin suchen soll (auf Übereinstimmung).
VG00-LV00
VG00-LV01
VG00-LV04

Mit dem aktuellen code, findet er keine Übereinstimmung:

Code: Alles auswählen

#!/usr/bin/env python

from __future__ import with_statement
import os,sys

# CTAB='/tmp/crypty'
CTAB='/etc/crypttab'
tmpR2='/tmp/tmp_crypt2.tmp'
times=0; ctimes=0

with open(CTAB,'r') as ctab_file:
        ctab=frozenset(line.strip() for line in ctab_file)
with open(tmpR2,'r') as tmp_file:
        ttmp=frozenset(line.strip() for line in tmp_file)
print ttmp.intersection(ctab)
Ich hab es vorläufig mit einem Umweg gelöst.

Code: Alles auswählen

#!/usr/bin/env python
import os,sys

# CTAB='/tmp/crypty'
CTAB='/etc/crypttab'
tmpR2='/tmp/tmp_crypt2.tmp'
times=0; ctimes=0; R=[]; R2=[]

tmpX=open(tmpR2,'r').readlines()
for cline in open(tmpR2,'r'):           # VG00-LV00 VG00-LV01 VG00-LV04
        cline=cline.strip()
        for T in open(CTAB,'r'):        # crypttab
                T=T.strip()
                if cline in T:
                        R.append('%s\n' %cline)   # addiere die Übereinstimmungen in Liste
                else:
                        pass

for LVI in tmpX:
        if not LVI in R:
                R2.append(LVI)   # addiere alle Unterschiede zwischen crypttab u. Liste
print(R2)[0]

# Output:  VG00-LV04
Oder gibt es auch eine direkte Inversion der "intersection" - Methode ?
Falls noch jemand was weiß, bin immer dankbar für Tipps und Anregungen.
Never miss a good opportunity to shut up ;-)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo

http://docs.python.org/library/stdtypes.html#frozenset.

Und bitte wirf doch mal einen Blick in PEP8 (besonders Namenskonventionen und Einrückung), benutze sprechende Bezeichner und vergiss die inline-Kommentare. Dein Code ist nahezu unlesbar und kaum bis gar nicht verständlich.

Geöffnete Dateien sollten ürigens auch wieder geschlossen werden. Das "with" wurde nicht umsonst vorgeschlagen ;-)

Bis dann
Sebastian
Das Leben ist wie ein Tennisball.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

virginiawalker hat geschrieben:Aber: Wenn ich von der echten /etc/crypttab lese, funktioniert es leider nicht mehr.
Naja, weil sie auch ganz anders ausschaut, als die Dateien die du als "Beispieldaten" gepostet hast. Hint: brauchbare Beispieldaten posten, dann bekommt man auch brauchbare Ergebnisse. Ich hab jetzt grad keine Zeit (und daraus folgend auch keine Lust) mehr dir noch ein Skript zu schreiben.
virginiawalker hat geschrieben:Oder gibt es auch eine direkte Inversion der "intersection" - Methode ?
Natürlich geht das auch mit intersection, du musst halt aus den Zeilen in der Crypttab die interessanten Teile rausholen und sie in ein Set bringen. Du kannst da etwa die String-Methode ``split()`` verwenden um das zu erreichen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
virginiawalker
User
Beiträge: 6
Registriert: Donnerstag 21. Januar 2010, 09:12
Wohnort: Ulm

Leonidas hat geschrieben:
virginiawalker hat geschrieben:Aber: Wenn ich von der echten /etc/crypttab lese, funktioniert es leider nicht mehr.
Naja, weil sie auch ganz anders ausschaut, als die Dateien die du als "Beispieldaten" gepostet hast. Hint: brauchbare Beispieldaten posten, dann bekommt man auch brauchbare Ergebnisse. Ich hab jetzt grad keine Zeit (und daraus folgend auch keine Lust) mehr dir noch ein Skript zu schreiben.
virginiawalker hat geschrieben:Oder gibt es auch eine direkte Inversion der "intersection" - Methode ?
Natürlich geht das auch mit intersection, du musst halt aus den Zeilen in der Crypttab die interessanten Teile rausholen und sie in ein Set bringen. Du kannst da etwa die String-Methode ``split()`` verwenden um das zu erreichen.
Nein, kein Problem Leonidas. Deine Methode war sauber, passt alles. Wollte mich nicht beschweren ;-) Ich hätte das mit der crypttab gleich angeben sollen...

Nochmal danke allerseits für die Tipps.
Never miss a good opportunity to shut up ;-)
Antworten