Sortieren nach options in einem ConfigParser

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
aga
User
Beiträge: 18
Registriert: Montag 12. März 2007, 15:36

Hallo!

Ich stehe for folgendem Problem:
ich habe ein ConfigParser objekt, das z.B. folgendes file (gekürzt) einliest:


[EtnProcesses]
existent = true
editable = true
type = text
mandatoryToFill = true
value =
defaultValue =
sequenceNumber = 2

[AllProcesses]
existent = true
editable = true
type = text
mandatoryToFill = true
value =
defaultValue =
sequenceNumber = 3

[processes]
existent = true
editable = true
type = text
mandatoryToFill = true
value =
defaultValue =
sequenceNumber = 1


und möchte eine Liste haben, die die sectionNames des ConfigParsers nach der option sequenceNumber sortiert enthält: sprich sie sollte so aussehen:
"processes", "EtnProcesses", "AllProcesses"

Da gibt's bestimmt eine elegante Lösung - nur komm ich nicht drauf...

danke im voraus
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Japp, ist sogar recht einfach:

Config:

Code: Alles auswählen

[EtnProcesses]
existent = true
editable = true
type = text
mandatoryToFill = true
value = none
defaultValue =
sequenceNumber = 2

[AllProcesses]
existent = true
editable = true
type = text
mandatoryToFill = true
value = none
defaultValue = none
sequenceNumber = 3

[tester]
sequenceNumber = 5

[processes]
existent = true
editable = true
type = text
mandatoryToFill = true
value = none
defaultValue = none
sequenceNumber = 1
Code:

Code: Alles auswählen

#-*- coding: utf-8 -*-


from ConfigParser import ConfigParser

config = ConfigParser()
config.read('t.ini')

numbers = list()

for section in config.sections():
    number = config.get(section, 'sequenceNumber')
    numbers.append((section, number))

def sorter(x, y):
    if x[1] < y[1]:
        return -1
    elif x[1] > y[1]:
        return 1
    else:
        return 0

numbers.sort(sorter)
print numbers
Ausgabe:

Code: Alles auswählen

[EnTeQuAk@ente-lappi development]$ python t.py
[('processes', '1'), ('EtnProcesses', '2'), ('AllProcesses', '3'), ('tester', '5')]
Man könnte es sicherlich auch mit einer Lambda Funktion realisieren, darauf hatte ich aber keinen Bock.

Weitere Informationen: [wiki]Sortierungs-Tutorium[/wiki]

MfG EnTeQuAk
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Das geht noch viel einfacher :)

Code: Alles auswählen

sections = sorted(config.sections(), lambda x, y: 
  cmp(config.getint(x, 'sequenceNumber'), config.getint(y, 'sequenceNumber'))
// ungetestet

..wird aber je nach Implementierung von config.getint eher langsam sein.
Zuletzt geändert von veers am Mittwoch 8. August 2007, 17:33, insgesamt 2-mal geändert.
BlackJack

@EnTeQuAk: Man sollte auf jeden Fall `getint()` statt `get()` benutzen sonst gibt's beim sortieren falsche Ergebnisse wenn es Zahlen mit unterschiedlicher Ziffernanzahl gibt.

`sorter()` ist viel zu kompliziert, die `cmp()`-Funktion macht das alles schon:

Code: Alles auswählen

def sorter(x, y):
    return cmp(x[1], y[1])
Man sollte aber lieber eine `key`-Funktion statt einer `cmp`-Funktion angeben, weil das schneller ist. Oder die Tupel andersherum anlegen, also mit der Nummer als erstes Element ─ dann braucht man gar keine zusätzliche Funktion, sondern kann einfach so sortieren.

Code: Alles auswählen

from ConfigParser import ConfigParser
from operator import itemgetter

def main():
    config = ConfigParser()
    config.read('test.ini')
    print map(itemgetter(1),
              sorted((config.getint(section, 'sequenceNumber'), section)
                     for section in config.sections()))
aga
User
Beiträge: 18
Registriert: Montag 12. März 2007, 15:36

danke - funkt! :D
Antworten