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.

Darren J. Fitzpatrick
quelle

Antworten:

153
d = {}
with open("file.txt") as f:
    for line in f:
       (key, val) = line.split()
       d[int(key)] = val
Vlad H.
quelle
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)
Ignacio Vazquez-Abrams
quelle
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),)}
wim
quelle
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)
tokland
quelle
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]
Samer Ayoub
quelle
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

Holger Bille
quelle
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)
VGE
quelle
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 :)

srami
quelle
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:]
Robel Robel Lingstuyl
quelle
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
A. West
quelle