问题
I am trying to make a dictionary from this file: with the key being the first word, and the values being all words afterwards.
andrew fred
fred
judy andrew fred
george judy andrew
john george
This is the code I have:
follows_file = open("C:\\Users\\Desktop\\Python\\follows.txt")
followers = {}
for line in follows_file: #==> [Judy Andrew Fred]
users = line.split(' ') #==> [Judy, andrew, Fred, ....]
follower = users[0] #==> [Judy]
followed_by = users[1:] #==> [Andrew, Fred]
for user in followed_by:
# Add the 'follower to the list of followers user
if user not in followers:
followers[user] = []
followers[user].append(follower)
print(followers.items())
When I print the follower and followed by variable, they are correct, but i'm having trouble adding them into the dictionary correctly; with this being the output
dict_items([('fred\n', ['andrew', 'judy']), ('andrew', ['judy']), ('judy' ['george']), ('andrew\n', ['george']), ('george', ['john'])])
My desired output would be
(Andrew[Fred])(Fred[])(judy[Andrew Fred])(George[Judy Fred])(john[george])
Any assistance is much appreciated!
回答1:
Edited answer, improved thanks to the comments from @PM2Ring and @IljaEverilä.
Here is my original solution using a dictionary comprehension
followers = {line.split()[0]: line.split()[1:] for line in follows_file}
A more efficient alternative proposed by @IljaEverilä, which avoids calling split
twice, is:
followers = {follower: followees for follower, *followees in map(str.split, follows_file)}
Result:
{'andrew': ['fred'],
'fred': [],
'george': ['judy', 'andrew'],
'john': ['george'],
'judy': ['andrew', 'fred']}
Note that both of the above solutions assume that your file contains no duplicate keys.
Don't forget to close your file afterwards:
follows_file.close()
Or better, just use a context manager, which handles the file closing for you:
with open('C:\\Users\\zacan\\Desktop\\Python\\follows.txt', 'r') as follows_file:
followers = {follower: followees for follower, *followees in map(str.split, follows_file)}
回答2:
You can use collections.defaultdict() as a dictionary factory and just append the users following a person, e.g.:
import collections
followers = collections.defaultdict(list) # use a dict factory to save some time on checks
with open("path/to/your_file", "r") as f: # open the file for reading
for line in f: # read the file line by line
users = line.split() # split on any white space
followers[users[0]] += users[1:] # append the followers for the current user
Which will produce, for your data:
{'andrew': ['fred'],
'fred': [],
'judy': ['andrew', 'fred'],
'george': ['judy', 'andrew'],
'john': ['george']}
This will also allow you to have multiple lists appended to the user on a repeating record - otherwise you can just use a normal dict
for followers
and set them as followers[users[0]] = users[1:]
.
The data structure you've shown as your desired output is not valid Python, do you really want it presented that way? I mean, if you insist you can do it as:
print("".join("({}[{}])".format(k, " ".join(v)) for k, v in followers.items()))
# (andrew[fred])(fred[])(judy[andrew fred])(george[judy andrew])(john[george])
回答3:
This is one solution using str.split
and a try
/ except
clause to capture instances where only a key exists.
Note io.StringIO lets us read from a string as if it were a file.
from io import StringIO
import csv
mystr = StringIO("""andrew fred
fred
judy andrew fred
george judy andrew
john george""")
# replace mystr with open("C:\\Users\\zacan\\Desktop\\Python\\follows.txt")
with mystr as follows_file:
d = {}
for users in csv.reader(follows_file):
try:
key, *value = users[0].split()
except ValueError:
key, value = users[0], []
d[key] = value
print(d)
{'andrew': ['fred'],
'fred': [],
'george': ['judy', 'andrew'],
'john': ['george'],
'judy': ['andrew', 'fred']}
回答4:
followers = dict()
with open('C:\\Users\\zacan\\Desktop\\Python\\follows.txt', 'r') as f:
for line in f:
users = line.split(' ')
followers[users[0]] = [_ for _ in users[1:]]
this should work, didn't test it
来源:https://stackoverflow.com/questions/50465705/making-a-dictionary-from-each-line-in-a-file