Zugriff auf einzelne Werte in Liste in Dictionary ohne []

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
pythoner
User
Beiträge: 22
Registriert: Dienstag 8. September 2015, 19:58

Hallo,

ich habe folgendes Dictionary mit einer Liste darin, kann die Werte füllen, aber leider nicht ohne die [] z.B. ['maint=0'] ausgeben.
Kann mir bitte jemand mitteilen, wie nur an maint=0 komme?

Code: Alles auswählen

index = {}

def add_to_index(index, hostname, info):
    if hostname not in index:
        index[hostname] = [info]
    else:
        index[hostname].append(info)

print "\nEinlesen der Datei idb.ini"
fobj = open(idb_file )
for line in fobj:
    hit = line.find("bladecenter:")
    if hit != -1:
        line = line.rstrip()
        name = "/bladecenter;" + line[line.find("[bladecenter:")+13:line.find("]")]
        if name != "":
            add_to_index(index, name, "")
    hit = line.find("network:")
    if hit != -1:
        line = line.rstrip()
        name = "/network;" + line[line.find("[network:")+9:line.find("]")]
        if name != "":
            add_to_index(index, name, "")
    hit = line.find("server:")
    if hit != -1:
        line = line.rstrip()
        name = "/server;" + line[line.find("[server:")+8:line.find("]")]
    hit = line.find("storage:")
    if hit != -1:
        line = line.rstrip()
        name = "/storage;" + line[line.find("[storage:")+9:line.find("]")]
        if name != "":
            add_to_index(index, name, "")
    hit = line.find("maint=")
    if hit != -1:
        hit = line.find("maint=")
        maint = re.findall("maint=.*", line.rstrip())
        if maint != "":
            add_to_index(index, name, maint)
        else:
            add_to_index(index, name, maint)
    hit = line.find("env=")
    if hit != -1:
        hit = line.find("env=")
        env = re.findall("env=.*", line.rstrip())
        if env != "":
            add_to_index(index, name, env)

fobj.close()

print index

for x in index.items():
    print "items: ", x, x[0], x[1][0], x[1][1]
    a, b = x[1]
    print "a:", a
    print "b:", b
Quelldatei:
[server:vm1001]
maint=0
env=0
sysgroup=test1

[storage:vm1002]
maint=0
env=0
sysgroup=test3

[server:vm1003]
maint=0
env=1
sysgroup=test3

[server:vm1004]
maint=0
env=0
sysgroup=test4
Ausgabe:
{'/server;vm1003': [['maint=0'], ['env=2']], '/server;vm1001': [['maint=0'], ['env=0']], '/storage;vm1002': ['', ['maint=0'], ['env=0']], '/server;vm1004': [['maint=0'], ['env=0']]}
items: ('/server;vm1003', [['maint=0'], ['env=1']]) /server;vm1003 ['maint=0'] ['env=1']
a: ['maint=0']
b: ['env=1']
...
Danke und Gruß
Pythoner
BlackJack

@pythoner: Dann schau Dir doch einfach mal an was `re.findall()` zurück gibt und was Du dann damit machst. Das ist irgendwie offensichtlich warum das Listen sind.

Dieses dauernde Zuweisen an `hit` ist überflüssig und `find()` mit dem Rückgabewert -1 ist auch nicht wirklich leicht verständlich. Für so etwas gibt es den ``in``-Operator. Und wenn man den Index tatsächlich verwendet sollte man nicht `find()` sondern `index()` verwenden, denn sonst kann es passieren das `find()` die -1 zurück gibt was aber auch ein gültiger Index zum Beispiel bei Listen ist, aber ziemlich sicher der falsche Wert. Und das fällt dann erst später auf oder erstmal gar nicht, bis man sich irgendwann mal über falsche Ergebnisse wundert.

Die ``if name != "":``-Tests wo man `name` in der Zeile davor eine nichtleere Zeichenkette zugewiesen hat sind irgendwie hochgradig überflüssig.

Ich würde ja als erstes mal schauen ob sich die ini-Datei nicht mit `ConfigParser` verarbeiten lässt. Und falls nicht einen eigenen, allgemeineren Parser für das Format schreiben.
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Ich würde doch eher vorschlagen nochmal die Basics anzulesen. Was ist ein Dictionary, was eine Liste, wie gebe ich den Inhalt einer Liste aus?
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
Benutzeravatar
sparrow
User
Beiträge: 4144
Registriert: Freitag 17. April 2009, 10:28

Vielleicht wäre es ganz gut die Eingangsdaten zu Posten, und das was du als Ergebnis haben möchtest.
Dein Parsen und zusammenbauen der Daten sieht ein bisschen sehr chaotisch aus. Mir erschließt sich dadurch nicht was du erreichen möchtest, bzw. wie die Struktur am Ende aussehen soll.
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

@pythoner: Du könntest Dir überlegen, in welchem Format Du die Daten am besten weiterverarbeiten kannst, und wie die ini-Datei aufgebaut ist, und dann einen allgemeinen Parser dafür schreiben, z.B. so:

Code: Alles auswählen

def parse_ini(idb_file):
    print "\nEinlesen der Datei idb.ini"
    result = {}
    with open(idb_file) as lines:
        for line in lines:
            line = line.strip()
            if line.startswith('[') and line.endswith(']'):
                device, name = line[1:-1].split(':', 1)
                current_section = {}
                result['/%s;%s' % (device, name)] = current_section
            elif '=' in line:
                key, value = line.split('=', 1)
                current_section[key] = value
            elif line:
                raise RuntimeError("syntax error: %s" %line)
    return result

print parse_ini('idb.ini')
BlackJack

@pythoner: `ConfigParser` aus der Standardbibliothek am Beispiel Deiner Beispiel *.ini:

Code: Alles auswählen

In [22]: cp = ConfigParser.SafeConfigParser()

In [23]: cp.read('test.ini')
Out[23]: ['test.ini']

In [24]: cp.sections()
Out[24]: ['server:vm1001', 'storage:vm1002', 'server:vm1003', 'server:vm1004']

In [25]: cp.options('server:vm1001')
Out[25]: ['maint', 'env', 'sysgroup']

In [26]: cp.has_option('server:vm1001', 'env')
Out[26]: True

In [27]: cp.has_option('server:vm1001', 'spam')
Out[27]: False

In [28]: cp.get('server:vm1001', 'env')
Out[28]: '0'

In [29]: cp.getint('server:vm1001', 'env')
Out[29]: 0

In [30]: cp.items('server:vm1001')
Out[30]: [('maint', '0'), ('env', '0'), ('sysgroup', 'test1')]

In [31]: dict(cp.items('server:vm1001'))
Out[31]: {'env': '0', 'maint': '0', 'sysgroup': 'test1'}
pythoner
User
Beiträge: 22
Registriert: Dienstag 8. September 2015, 19:58

Hallo,
vielen Dank für die tollen Informationen.
Die Nutzung von ConfigParser ist klasse. Damit kann ich mein Problem lösen.
Danke und Gruß
Pythoner
Antworten