Odczytanie słownika z pliku

Odczytanie słownika z pliku
Arwena Marenwen
Arwena Marenwen
  • Rejestracja:około 6 lat
  • Ostatnio:ponad 5 lat
  • Postów:8
0

Mam zapisanyw pliku tekstowym txt słownik w taki formacie: {'k': '000', 'o': '001', 't': '010', '.': '011', 'a': '10', ' ': '110', 'l': '1110', 'm': '1111'}
Jak odczytać ten słownik z pliku?
Za słwonikiem mam w pliku jeszcze dalszy tekst

superdurszlak
  • Rejestracja:prawie 7 lat
  • Ostatnio:około 20 godzin
  • Lokalizacja:Kraków
  • Postów:2000
0
Arwena Marenwen napisał(a):

Mam zapisanyw pliku tekstowym txt słownik w taki formacie: {'k': '000', 'o': '001', 't': '010', '.': '011', 'a': '10', ' ': '110', 'l': '1110', 'm': '1111'}

Gdyby w pliku był wyłącznie słownik lub podobna struktura, możnaby wprost wciągnąć go przez moduł json lub ew. yaml dla plików w formacie YAML:

Kopiuj
import json

with open("plik.json", "r") as f:
  slownik = json.load(f)

Jeśli byłby w pliku z jeszcze jakimiś treściami, to zakładając że masz już gotowy sposób na wycięcie słownika z pliku:

Kopiuj
import json

with open("zagmatwany_plik.txt", "r") as f:
  wyciety_tekst = wytnij_slownik(f.read())
  slownik = json.loads(wyciety_tekst)

Jak odczytać ten słownik z pliku?

Jak wyżej

Za słwonikiem mam w pliku jeszcze dalszy tekst

Jak słownik jest oddzielony od "dalszego tekstu"? Jak wygląda ten plik? Jeśli to jest zawsze słownik, to zawsze możesz złapać go regexpem, który wyszuka klamry, i to wyciąć:

Kopiuj
import re

with open("zagmatwany_plik.txt", "r") as f:
  tekst = f.read()
  match = re.search('({.*})', tekst, re.DOTALL)
  if match is not None:
    wyciety_tekst = match.group(1)
    slownik = json.loads(wyciety_tekst)
    

Tu masz link do fajnego toola do zabawy regexami z przykładem: Regex101


edytowany 3x, ostatnio: superdurszlak
Arwena Marenwen
Arwena Marenwen
nie mam pliku w formacie yaml slownik nie jestw zadne sposob oddzielony od teksu. Po nawiasie klamrowym po prostu zaczyna sie tekst
superdurszlak
a próbowałeś/aś z modułem json i wycinaniem z pliku? ostatni snippet
lion137
  • Rejestracja:około 8 lat
  • Ostatnio:około 8 godzin
  • Postów:4928
0

  • Rejestracja:około 6 lat
  • Ostatnio:ponad rok
0
Kopiuj
>>> s = open('foo.txt').read()

>>> eval(s[:s.find('}') + 1])
{'k': '000', 'o': '001', 't': '010', '.': '011', 'a': '10', ' ': '110', 'l': '1110', 'm': '1111'}

>>> 

(Zakładam, że ufasz danym wejściowym i nie jest to kod, który trafi na produkcję.)

superdurszlak
  • Rejestracja:prawie 7 lat
  • Ostatnio:około 20 godzin
  • Lokalizacja:Kraków
  • Postów:2000
1
Mózg napisał(a):
Kopiuj
>>> eval(s[:s.find('}') + 1])
{'k': '000', 'o': '001', 't': '010', '.': '011', 'a': '10', ' ': '110', 'l': '1110', 'm': '1111'}

jaka jest niby przewaga rozwiązania z eval nad json.loads poza tym, że ktoś uprzejmy mógłby Ci wpakować tutaj

Kopiuj
print("Hello World!")#}

albo coś znacznie brzydszego?

Np. nic nie stoi na przeszkodzie, by do środka wyrażenia wepchnąć sobie exec i potem to już hulaj dusza:

Kopiuj
{ 'busted': exec('def fun():\\n  print("Mam Cie!")\\n  return fun()\\nfun()') }

edytowany 3x, ostatnio: superdurszlak
enedil
  • Rejestracja:prawie 12 lat
  • Ostatnio:około 9 godzin
  • Postów:1027
0

No, ast.literal_eval jest tutaj odpowiednim rozwiązaniem. Jest bezpieczny, ma też znaczącą przewagę nad json.loads - słownik to nie jest json, i chociażby w jsonie są wymagane cudzysłowy (zamiast apostrofów), tak więc nie każdy poprawny słownik będzie sparsowany.

Guaz
Gdzieś widziałem sposób do zrobienia w balona literal_eval, niestety ani nie pamiętam gdzie, ani konkretnie jak. Nawet nie mogę tego odkopać w google. Ale rzucam w eter, może ktoś akurat też to widział i ma link aby się podzielić, wspominam jako ciekawostkę :).
  • Rejestracja:około 6 lat
  • Ostatnio:ponad rok
0
superdurszlak napisał(a):

jaka jest niby przewaga rozwiązania z eval nad json.loads

Moje rozwiązanie DZIAŁA i jest proste. Co do reszty:

Mózg napisał(a):

(Zakładam, że ufasz danym wejściowym i nie jest to kod, który trafi na produkcję.)

edytowany 1x, ostatnio: Mózg
enedil
Jest też tragicznie wolne :p a nigdy też nie wiesz co się z Twoim kodem stanie - w szczególności, nigdy nie powinno się pisać kodu, który się nie nadaje na produkcję (chyba, że wiesz, że kodu tego przestaniesz używać w przeciągu pół godziny).
Proponowany przez Ciebie ast.literal_eval jest wolniejszy.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.