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
Odczytanie słownika z pliku
- Rejestracja: dni
- Ostatnio: dni
- Postów: 8
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Kraków
- Postów: 2002
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:
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:
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ąć:
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
- Rejestracja: dni
- Ostatnio: dni
- Postów: 5023
- Rejestracja: dni
- Ostatnio: dni
>>> 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ę.)
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Kraków
- Postów: 2002
Mózg napisał(a):
>>> 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
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:
{ 'busted': exec('def fun():\\n print("Mam Cie!")\\n return fun()\\nfun()') }
- Rejestracja: dni
- Ostatnio: dni
- Postów: 1028
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.
- Rejestracja: dni
- Ostatnio: dni
superdurszlak napisał(a):
jaka jest niby przewaga rozwiązania z
evalnadjson.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ę.)