Seite 1 von 1

Sortieren nach options in einem ConfigParser

Verfasst: Mittwoch 8. August 2007, 16:41
von aga
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

Verfasst: Mittwoch 8. August 2007, 17:07
von EnTeQuAk
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

Verfasst: Mittwoch 8. August 2007, 17:24
von veers
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.

Verfasst: Mittwoch 8. August 2007, 17:27
von 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()))

Verfasst: Donnerstag 9. August 2007, 09:06
von aga
danke - funkt! :D