Making a dictionary from each line in a file

点点圈 提交于 2019-12-02 13:21:21

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)}

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])

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']}
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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!