问题
I'm having trouble reading from a file and returning the contents as a dictionary. Each file contains numbers separated by \n and the goal is to count the numbers returning each number as a key and the value of the key is the number of times it was in the file.
Example: when filea.txt
contains
"1\n1\n1\n2\n3\n3\n3\n3\n5\n"
the function should return
{1:3,2:1,3:4,5:1}
when filea.txt
contains "100\n100\n3\n100\n9\n9\n"
the function should return {100:3, 3:1, 9:2}
when fileb.txt
contains "13\n13\n13\n13\n13\n13\n13\n13\n"
the function should return {13:8}
Here is my current attempt:
def file_counts(filename):
a = open('filea.txt')
b = open('fileb.txt')
info = a.read()
info2 = b.read()
a.close()
b.close()
if info == True:
return (dict(collections.Counter(info)))
elif info2 == True:
return (dict(collections.Counter(info2)))
else:
return None
Currently this is giving me the error no such file or directory and I believe it's because the contents of the file change in different test cases. So filea can contain different information and the function needs to account for this. Thanks to anyone who helps
回答1:
Something like this should suffice. Keep in mind that no validation has been done. Eg, blank lines, non-numeric characters. In your question is seemed like the numbers should be converted to an integer but your code doesn't so I included it anyway.
from collections import Counter
def file_counts(filename):
# Open file for reading
with open(filename, 'r') as file:
data = []
# Go through each line of the file
for line in file:
value = int(line)
data.append(value)
return dict(Counter(data))
if __name__ == '__main__':
filename = 'testfile.txt'
print(file_counts(filename))
Issues you had were.
def file_counts(filename):
a = open('filea.txt')
b = open('fileb.txt')
You are reading two files and ignoring the filename given as a parameter.
info = a.read()
This will read in the whole file, typically not the best when it comes to large files.
if info == True:
info
will never be True
as it is a string.
return (dict(collections.Counter(info)))
This is typically fine, however you haven't formatted info as it is still a string, so your dictionary included the \n
characters, it doesn't work for digits with more than 1 character as it counts each individual character.
You are most likely getting an IOError. You need your text files in the same directory as your python file if you want to just use the filename, otherwise you have to supply the file path
回答2:
From your statement, I assume you received an IOError
such as:
IOError: [Errno 2] No such file or directory: 'filea.txt'
If you receive this error, it is because open
cannot find a file in the current working directory that matches the filename you are asking it to fetch. You need to add the path to the beginning of filename such as /home/username/project/filea.txt
to make sure python is searching in the correct directory.
Once you are able to open your file and are past the IOError, your code has a few kinks.
First, let's look at dict(collections.Counter(info))
>>> info = "100\n100\n3\n100\n9\n9\n"
>>> dict(collections.Counter(info))
{'1': 3, '0': 6, '3': 1, '\n': 6, '9': 2}
As we can see, collections.Counter()
is parsing each character in the string and counting the occurrence of each one. Therefore '1', '0' and '3' are each counted three times rather than counting 100 three times. Instead, you could make a list of the values as below:
>>> info = info.strip() # removes the last \n on the right
>>> nums = info.split('\n') # breaks up the string into a list of elements
>>> print(nums)
['100', '100', '3', '100', '9', '9']
>>> print(dict(collections.Counter(nums)))
{'9': 2, '100': 3, '3': 1}
You still have a few errors concerning your input and the if then statements at the end but I'll let you take a stab at them first. GL!
来源:https://stackoverflow.com/questions/40457121/python-obtain-a-list-of-numbers-from-a-file-and-return-as-dict-representation