Wie konvertiere ich eine Datei in ein Wörterbuch?


93

Ich habe eine Datei mit zwei Spalten, dh

1 a 
2 b 
3 c

Ich möchte diese Datei in einem Wörterbuch so lesen, dass Spalte 1 der Schlüssel und Spalte 2 der Wert ist, dh

d = {1:'a', 2:'b', 3:'c'}

Die Datei ist klein, daher ist Effizienz kein Problem.

Antworten:


153
d = {}
with open("file.txt") as f:
    for line in f:
       (key, val) = line.split()
       d[int(key)] = val

1
Könnten Sie das mit Aussage erklären?
VGE

12
withwird hier verwendet, um die Dateibereinigung durchzuführen. Wenn Sie den Block verlassen (entweder nur durch normalen Ausführungsablauf oder durch eine Ausnahme), wird die Datei automatisch geschlossen. Weitere Informationen zu Kontextmanagern
Vlad H

1
for line in open("file.txt"):Bereinigen Sie auf die gleiche Weise. Und wenn f ein lokaler Wert fist, wird dieser freigegeben, wenn der Bereich verloren geht. Der einzige Fall, in dem diese Anweisung nützlich ist, ist für lange Funktionen (nicht gut für die Qualität) oder wenn Sie eine globale Variable verwenden.
VGE

1
@VGE, for line in open('file.txt')ist nicht tun Bereinigung auf die gleiche Weise. Nicht alle Python-Implementierungen sind gleich. withgarantiert, dass die Datei geschlossen wird, wenn der Block verlassen wird. Wenn die forLeitung fertig ist, close kann aufgerufen werden. CPythones wird, aber Versionen wie IronPythonhaben faule Müllsammler.
Mark Tolonen

2
Ist int hier wirklich notwendig? Vielleicht wollte er, dass die Zahlen Zeichenfolgen sind?
GL2014

15

Dadurch bleibt der Schlüssel als Zeichenfolge:

with open('infile.txt') as f:
  d = dict(x.rstrip().split(None, 1) for x in f)

2
Ein einfaches dict([line.split() for line in f])ist ausreichend, imo.
user225312

@sukhbir: Wenn du eine Frage liest, wirst du sehen, dass das nicht das ist, was op will.
SilentGhost

@ SilentGhost: Ich habe gelesen, dass das OP Schlüssel als Ganzzahlen haben möchte, aber Ignacios Lösung (sowie die von mir gelöschte) hat Schlüssel als Zeichenfolge (wie von Ignacio selbst hervorgehoben).
user225312

Ich war verwirrt, warum wir [] nicht brauchen, wenn wir das Diktatargument weitergeben. dh dict([x.rstrip().split(None, 1) for x in f])statt dict(x.rstrip().split(None, 1) for x in f). Für diejenigen, die dasselbe denken, ist Ersteres ein Generatorausdruck anstelle des Listenverständnisses, wie hier erläutert: python.org/dev/peps/pep-0289(PEP-289) . Etwas Neues gelernt!
Peaxol

1
@peaxol: Wir verwenden einen Generatorausdruck anstelle eines Listenverständnisses, um keine Zwischenliste zu erstellen.
Ignacio Vazquez-Abrams

7

Wenn Ihre Python - Version 2.7+ ist, können Sie auch eine Verwendung dict Verständnis wie:

with open('infile.txt') as f:
  {int(k): v for line in f for (k, v) in (line.strip().split(None, 1),)}

5
def get_pair(line):
    key, sep, value = line.strip().partition(" ")
    return int(key), value

with open("file.txt") as fd:    
    d = dict(get_pair(line) for line in fd)

1
warum nicht partition? und withAussage?
SilentGhost

@ SilentGhost: Ich wusste nichts über Partition! aber warum ist es in diesem Fall besser, str.split zu machen? zu "mit": Vielleicht können Sie dies für mich klarstellen: Reicht es nicht aus, den Bereich für das Schließen des Dateideskriptors zu verlassen? Ich denke, in einer Ausnahme bleibt die Datei main offen, ich werde sie ändern.
Tokland

partitionist schneller und wird genau für diesen Zweck erstellt.
SilentGhost

Ob der Deskriptor geschlossen ist oder nicht, ist ein Detail der Implementierung. withist ein einfacher Weg, um dies sicherzustellen.
SilentGhost

es würde immer noch erfordern strip, würde ich sagen.
SilentGhost

3

Durch Wörterbuchverständnis

d = { line.split()[0] : line.split()[1] for line in open("file.txt") }

Oder von Pandas

import pandas as pd 
d = pd.read_csv("file.txt", delimiter=" ", header = None).to_dict()[0]

Von Pandas nimmt nur die erste Spalte
Maulik Madhavi

1
@Samer Ayoub Die obige Lösung (Wörterbuchverständnis) funktioniert, wenn sowohl Schlüssel als auch Wert ein Wort lang sind. Wenn meine Textdatei folgende Daten enthält. Wie mache ich das Jahr als Schlüssel und das Gewinnerteam als Werte? 1903 Boston Americans 1904 No World Series 1905 New York Giants 1906 Chicago White Sox 1907 Chicago Cubs 1908 Chicago Cubs
Ridhi

1
@Ridhi Entschuldigung für die verspätete Antwort. Sie können entweder nur auf dem ersten Platz aufteilen stackoverflow.com/questions/30636248/… oder einen regulären Ausdruck als Argument für split () verwenden
Samer Ayoub

@ SamerAyoub- Danke.
Ridhi

1

IMHO etwas pythonischer, um Generatoren zu verwenden (wahrscheinlich benötigen Sie 2.7+ dafür):

with open('infile.txt') as fd:
    pairs = (line.split(None) for line in fd)
    res   = {int(pair[0]):pair[1] for pair in pairs if len(pair) == 2 and pair[0].isdigit()}

Dadurch werden auch Zeilen herausgefiltert, die nicht mit einer Ganzzahl beginnen oder nicht genau zwei Elemente enthalten


0
import re

my_file = open('file.txt','r')
d = {}
for i in my_file:
  g = re.search(r'(\d+)\s+(.*)', i) # glob line containing an int and a string
  d[int(g.group(1))] = g.group(2)

9
re? Ernsthaft?
SilentGhost

Ich denke nicht, dass dies der beste Ansatz ist.
Donovan

@Seafoid sagte: "Die Datei ist klein, daher ist Effizienz kein Problem." split()funktioniert nicht fast lautlos, wenn das Dateiformat nicht normal ist.
VGE

0

Wenn Sie einen Liner lieben, versuchen Sie:

d=eval('{'+re.sub('\'[\s]*?\'','\':\'',re.sub(r'([^'+input('SEP: ')+',]+)','\''+r'\1'+'\'',open(input('FILE: ')).read().rstrip('\n').replace('\n',',')))+'}')

Eingabe DATEI = Pfad zur Datei, SEP = Schlüssel-Wert-Trennzeichen

Nicht die eleganteste oder effizienteste Art, aber trotzdem sehr interessant :)


0

Hier ist eine weitere Option ...

events = {}
for line in csv.reader(open(os.path.join(path, 'events.txt'), "rb")):
    if line[0][0] == "#":
        continue
    events[line[0]] = line[1] if len(line) == 2 else line[1:]

0

Einfache Option

Die meisten Methoden zum Speichern eines Wörterbuchs verwenden JSON, Pickle oder Zeilenlesen. Vorausgesetzt, Sie bearbeiten das Wörterbuch nicht außerhalb von Python, sollte diese einfache Methode auch für komplexe Wörterbücher ausreichen. Obwohl Pickle für größere Wörterbücher besser ist.

x = {1:'a', 2:'b', 3:'c'}
f = 'file.txt'
print(x, file=open(f,'w'))    # file.txt >>> {1:'a', 2:'b', 3:'c'}
y = eval(open(f,'r').read())
print(x==y)                   # >>> True
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.