Seite 1 von 1

Zwei Zeilen aus datei zu einem Dictionary verarbeiten

Verfasst: Dienstag 8. November 2016, 20:44
von Wohnbus Altano
Hallo,
ich habe das Problem dass ich nicht rausbekomme wie ich zwei Zeilen einer Datei zu einem Wertepaar verarbeite.

Code: Alles auswählen

W={}
File=open ("/storage/emulated/0/qpython/Wurzel.txt","r")
for wert in File:
    Zahl=wert.strip ()
    ?
    W.update({Zahl:????})
Die Txt Datei: Der Code sieht bisher so aus de verarbeitungsteil ist auch schon geschrieben.
Die Zeile wo das Fragezeichen steht weiß ich nicht.
Danke für eure Hilfe.

LG Altano

Re: Zwei Zeilen aus datei zu einem Dictionary verarbeiten

Verfasst: Dienstag 8. November 2016, 20:59
von BlackJack
@Wohnbus Altano: Wenn Du zwei Zeilen hast und die etwas unterschiedliches bedeuten, dann solltest Du keine Schleife schreiben die mit jeder Zeile etwas macht, und zwar das gleiche. Öffne die Datei und lass Dir die jeweilige Zeile durch einen `next()`-Aufruf mit dem Dateiobjekt als Argument geben.

Die Namen sind nicht gut gewählt. Einbuchstabige Namen sind selten beschreibend genug. Die Schreibweise entspricht auch nicht dem Style Guide for Python Code.

`update()` ist hier die falsche Methode. Um *ein* Schlüssel/Wert-Paar hinzuzufügen würde man nicht erst umständlich ein neues Wörterbuch mit diesem Paar erstellen und an die `update()`-Methode übergeben, sondern mit der []-Syntax eben diesem einen Schlüssel den Wert zuordnen.

Re: Zwei Zeilen aus datei zu einem Dictionary verarbeiten

Verfasst: Mittwoch 9. November 2016, 07:10
von heiner88
Du kannst auch die Datei als Ganzes einlesen und in eine Liste umwandeln.
Danach die Liste in ein Dict umwandeln.

Code: Alles auswählen

with open(...) as file:
     liste = file.read().splitlines()

print(liste)

Re: Zwei Zeilen aus datei zu einem Dictionary verarbeiten

Verfasst: Mittwoch 9. November 2016, 08:53
von Sirius3
@heiner88: wenn Du eine Schleife über ein File-Objekt durch eine Schleife über eine Liste ersetzt, bist Du noch nicht wirklich weiter.

@Wohnbus Altano: es gibt verschiedene Möglichkeiten, jeweils zwei Zeilen zu Paaren zu kombinieren. Z.B. so:

Code: Alles auswählen

roots = {}
with open(FILENAME) as lines:
    for key, value in zip(lines, lines):
        roots[key.strip()] = value.strip()
oder per Dictionary-Comprehension:

Code: Alles auswählen

with open(FILENAME) as lines:
    roots = {key.strip(): value.strip() for key, value in zip(lines, lines)}

Re: Zwei Zeilen aus datei zu einem Dictionary verarbeiten

Verfasst: Mittwoch 9. November 2016, 09:22
von heiner88
Auf eine Liste kann ich wahlfrei zugreifen, auf eine Datei nur sequentiell.
Natürlich sind deine Lösungen eleganter, aber wie soll da ein Anfänger draufkommen.

Code: Alles auswählen

#python3
with open("wurzel.txt") as file:
     liste = file.read().splitlines()
print(liste)

i = 0
w = {}
while i+1 < len(liste):
    w[liste[i]] = liste[i+1]
    i = i + 2
     
print(w)

Re: Zwei Zeilen aus datei zu einem Dictionary verarbeiten

Verfasst: Mittwoch 9. November 2016, 09:49
von Sirius3
@heiner88: so wie Du schreibst, schreibt man in Programmiersprachen, die keine Iteratoren kennen, z.B. BASIC oder C.
Ich behaupte ja nicht, dass ein Anfänger auf meine Lösung kommt, deshalb zeige ich sie ja hier. Aber ein Anfänger soll halt lernen, wie man solche oder ähnliche Probleme mit dem typischen Muster löst. Liste, while-Schleife und Index ist keine Lösung, weil sie die Sprache nicht nutzt, so lernt der Anfänger kein Python, sondern BASIC mit der Syntax von Python.

Re: Zwei Zeilen aus datei zu einem Dictionary verarbeiten

Verfasst: Mittwoch 9. November 2016, 12:19
von heiner88
Jetzt bin ich noch auf die next()-Lösung von Blackjack gespannt.

Re: Zwei Zeilen aus datei zu einem Dictionary verarbeiten

Verfasst: Mittwoch 9. November 2016, 12:32
von BlackJack

Code: Alles auswählen

#!/usr/bin/env python
from __future__ import absolute_import, division, print_function


def main():
    with open('wurzel.txt') as lines:
        mapping = {(next(lines)).rstrip(): next(lines).rstrip()}
    print(mapping)


if __name__ == '__main__':
    main()
Wobei für ein Schlüssel/Wert-Paar ein Wörterbuch nicht so wirklich sinnvoll ist. Und wenn in den Zeilen Zahlendarstellungen stehen, man die vielleicht auch in tatsächliche Zahltypen umwandeln möchte.

Re: Zwei Zeilen aus datei zu einem Dictionary verarbeiten

Verfasst: Mittwoch 9. November 2016, 14:19
von DeaD_EyE
Ich hatte mal ein bisschen mit Generatoren experimentiert. Ich wollte etwas wie eine Eierlegende Wollmilchsau.

http://pastebin.com/bra6GUxH

Code: Alles auswählen

# This could be improved.
 
def chunker(iterable, num):
    """
   Returns an generator which yields the available chunks.
   If the last chunk is incomplete, it'll be cut off.
   """
    iterator = iter(iterable)
    while iterator:
        ret = []
        for _ in range(num):
            try:
                ret.append(next(iterator))
            except StopIteration:
                return
        else:
            yield ret
Hier ein Beispiel:

Code: Alles auswählen

s = 'Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6'
ret = {}
for k, v, in chunker(s.splitlines(), 2): #splitlines ist hier wichtig
    ret.update({k.strip(): v.strip()})

# {'Line 1': 'Line 2', 'Line 3': 'Line 4', 'Line 5': 'Line 6'}
Mit Dateien: example.txt

Code: Alles auswählen

Foo
42
Bar
43
FooBar
45
BarFoo
55
Missing!!!!!!

Code: Alles auswählen

with open('example.txt') as fd:
    ret = {}
    for k, v in chunker(fd, 2):
        ret.update({k.strip(): v.strip()})

# ret: {'Bar': '43', 'BarFoo': '55', 'Foo': '42', 'FooBar': '45'}
Missing!!!!!! taucht nicht auf, da danach StopIteration ausgelöst wird, obwohl die Anzahl der Elemente noch nicht erreicht ist.
Je nach Anforderung kann es aber auch gut sein, wenn man eine Exception auslöst. Kommt halt drauf an wie sauber die Daten sind, die rein kommen.

Re: Zwei Zeilen aus datei zu einem Dictionary verarbeiten

Verfasst: Mittwoch 9. November 2016, 14:35
von Sirius3
@DeaD_EyE: um ein Element eines Wörterbuchs zu setzen, nimmt man nicht update sondern die Eckigen Klammern. Bei Deinem chunker ist die while-Bedingung immer erfüllt, weil ein Iterator immer "wahr" ist. `while True:` wäre daher klarer. Einen else-Block bei einem for ohne break ist witzlos.
Da eine StopIteration eine "normale" Exception für Generatoren ist, braucht man die erst gar nicht abzufangen:

Code: Alles auswählen

def chunker(iterable, num):
    """
    Returns an generator which yields the available chunks.
    If the last chunk is incomplete, it'll be cut off.
    """
    iterator = iter(iterable)
    while True:
        yield [next(iterator) for _ in range(num)]