Как подсчитать объекты / подстроки в специально отформатированном файле? - PullRequest
2 голосов
/ 02 мая 2020

У меня есть файл, отформатированный таким образом -

{'apple': 4, 'orange': 3, 'peach': 1}
{}
{'apple': 1, 'banana': 1}
{'peach': 1}
{}
{}
{'pear': 3}
...

[10k more lines like this]

Я хочу создать новый текстовый файл для хранения общего количества каждого из этих фруктов / объектов, таких как это -

apple:110
banana:200
pineapple:50
...

Как мне это сделать?

Моя попытка: я пытался использовать Python ( Если это сбивает с толку, пожалуйста, пропустите ) -

f = open("fruits.txt","r")
lines = f.readlines()
f.close()
g = open("number_of_fruits.txt","a")

for line in lines:                           #Iterating through every line,
    for character in "{}'":                       #Removing extra characters,
        line = line.replace(character, "")    

    for i in range(0,line.count(":")):            #Using the number of colons as a counter,
        line = line[ [m.start() for m in re.finditer("[a-z]",line)][i] : [m.start() for m in re.finditer("[0-9]",line)][i] + 1 ] #Slice the line like this - line[ith time I detect any letter : ith time I detect any number + 1]
        #And then somehow store that number in temp, slicing however needed for every new fruit
        #Open a new file
        #First look if any of the fruits in my line already exist
        #If they do:
            #Convert that sliced number part of string to integer, add temp to it, and write it back to the file
        #else:
            #Make a newline entry with the object name and the sliced number from line.

Количество функций в Python очень ошеломляюще для начала. И на данный момент я просто рассматриваю возможность использования C, и это уже ужасная идея.

Ответы [ 3 ]

4 голосов
/ 02 мая 2020

Избегайте использования eval.

Я бы предпочел трактовать его как JSON, если вы можете гарантировать, что форматирование будет таким, как указано выше.

import json
from collections import Counter
with open('fruits.txt') as f:
    counts = Counter()
    for line in f.readlines():
        counts.update(json.loads(line.replace("'", '"')))

Если вы хотите вывод, как определено выше:

for fruit, count in counts.items():
    print(f"{fruit}:{count}")

Обновленный ответ

Основано на предложении @ DarryIG literal_eval в комментариях, отрицает JSON use.

from ast import literal_eval
from collections import Counter
with open('fruits.txt') as f:
    counts = Counter()
    for line in f.readlines():
        counts.update(literal_eval(line))
1 голос
/ 02 мая 2020

Вы можете использовать встроенные функции python, такие как literal_eval для оценки каждой строки в словарях в python:

from ast import literal_eval
from collections import defaultdict, Counter

with open("input.txt", 'r') as inputFile:
  counts = Counter()
  for line in inputFile:
    a = literal_eval(line)
    counts.update(Counter(a))

print(dict(counts))

вывод:

{'apple': 5, 'orange': 3, 'banana': 1, 'peach': 2, 'pear': 3}

1 голос
/ 02 мая 2020

с использованием defaultdict и json

import json
from collections import defaultdict

result = defaultdict(int)
with open('fruits.txt') as f:
    for line in f:
        data = json.loads(line.replace("'", '"'))
        for fruit, num in data.items():
            result[fruit] += num
print(result)

вывод

defaultdict(<class 'int'>, {'apple': 5, 'orange': 3, 'peach': 2, 'banana': 1, 'pear': 3})

РЕДАКТИРОВАТЬ: Я бы рекомендовал использовать ответ @BenjaminRowell (я проголосовал за него). Я оставлю это только для краткости.

...