Tworzenie tablicy słowników odczytując z pliku tekstowego

0

Python 3.9.7
Dzień dobry, jestem początkującym Pythona i mam zagwozdkę, którą muszę rozwiązać by zaspokoić swoją naukę:

Zadanie polega zwróceniu tablicy słowników odczytując kolejno linijki z pliku tekstowego.

Plik tekstowy ma postać:
wylosowane:[4, 5, 7];dane:(3, 10);ile:0;czas:1434482711.67
wylosowane:[8, 9, 1];dane:(5, 6);ile:1;czas:1632321711.67
...

Gdzie za każdym razem w programie głównym za pomocą funkcji zapisz_str(nazwapliku) zapisują się dane do owego pliku tekstowego co do losowania wybranego przez użytkownika.

Udało mi się rozwiązać problem dla sytuacji:

str = "E:11, K:19, L:21"

slownik_konwert = dict((x, int(y))
                     for x, y in (element.split(':')
                                  for element in str.split(', ')))

print("Konwerter dla : ", slownik_konwert)
print(type(slownik_konwert))

Output:
Konwerter dla: {'E': 11, 'K': 19, 'L': 21}
<class 'dict'>

Lecz problem polega na tym, że ten algorytm nie działa dla podanego pliku tekstowego, ponieważ wartość klucza 'wylosowane' to lista, 'dane' to (int,int), 'ile' to (int), a 'czas' to time.time() czyli float. Jak można zapisać funkcję czytaj_str(nazwapliku) aby zwracała tablicę słowników? PS. 'ile' zwraca ilość trafień sukcesywnych użytkownika czyli długość listy liczby trafionych cyfr czyli int jako pojedyńczą liczbe.

Problem został rozwiązany dla .json

def czytaj_json(nazwapliku):
    """Funkcja odczytuje dane w formacie json z pliku"""
    dane = []
    if os.path.exists(nazwapliku):
        with open(nazwapliku, "r") as plik:
            dane = json.load(plik)   #Zawartość podanego pliku dekodujemy do listy
    return dane

def zapisz_json(nazwapliku, dane):
    """Funkcja zapisuje dane w formacie json do pliku"""
    with open(nazwapliku, "w") as plik:
        json.dump(dane, plik)

Zawartość pliku Remik.json po kilku próbach:
#[{"czas": 1631043787.1202095, "dane": [1, 1], "wylosowane": [1], "ile": 1}, {"czas": 1631043857.316818, "dane": [1, 1], "wylosowane": [1], "ile": 1}]

Lecz interesuje mnie pominięcie .json.

Dla chętnych też jest problem w zapisz_str(nazwapliku, dane):

def zapisz_str(nazwapliku, dane):
    """Funkcja zapisuje dane w formacie txt do pliku"""
    with open(nazwapliku, "w") as plik:
        for slownik in dane:
            linia = [k + ":" + str(w) for k, w in slownik.iteritems()]
            linia = ";".join(linia)
            plik.write(linia+"\n")

Ponieważ w mojej wersji Pythona nie ma już .iteritems.

1

Niepotrzebnie coś kombinujesz.

with codecs.open("plik.txt","rb") as input_file:
    return [parse_line(line) for line in file]    

Teraz potrzebujesz tylko napisać funkcje która parsuje jedną linię z pliku.Trochę ryzykowne (bo eval więc musisz ufać tym danym) ale najłatwiejsze rozwiązanie to:

data="wylosowane:[4, 5, 7];dane:(3, 10);ile:0;czas:1434482711.67"
fields = [field.split(":") for field in data.split(";")]
result = { name: eval(value) for name,value in fields}

Ponieważ w mojej wersji Pythona nie ma już .iteritems.

Bo .items() zwraca to co kiedyś .iteritems()

1

@Shalom: można użyć ast.literal_eval, jest dużo bezpieczniejszy:

>>> unsafe1 = eval("print('Boooom!')")
Boooom!
>>> unsafe2 = eval("[4, 5, 7]")
>>> unsafe2
[4, 5, 7]
>>> less_unsafe1 = ast.literal_eval("print('Boooom!')")
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    less_unsafe1 = ast.literal_eval("print('Boooom!')")
  File "/usr/lib/python3.9/ast.py", line 105, in literal_eval
    return _convert(node_or_string)
  File "/usr/lib/python3.9/ast.py", line 104, in _convert
    return _convert_signed_num(node)
  File "/usr/lib/python3.9/ast.py", line 78, in _convert_signed_num
    return _convert_num(node)
  File "/usr/lib/python3.9/ast.py", line 69, in _convert_num
    _raise_malformed_node(node)
  File "/usr/lib/python3.9/ast.py", line 66, in _raise_malformed_node
    raise ValueError(f'malformed node or string: {node!r}')
ValueError: malformed node or string: <ast.Call object at 0x7f8b33f49d60>
>>> less_unsafe2 = ast.literal_eval("[4, 5, 7]")
>>> less_unsafe2
[4, 5, 7]

1 użytkowników online, w tym zalogowanych: 0, gości: 1