New to python Creating two Dictionaries from a file need specific lines

Go To StackoverFlow.com

1

I'm trying to build two seperate dictionaries with a file thats arranged in this format:

I need to take the name's reverse it so first name then last name, for the first dictionary I need to take the first name as the key and the other names in the first block as the values, ie, list of strings.

The second dictionary I need to again use the first name as the key ad the group or groups they belong to as the value.

I have figured out how to reverse the names using the comma to split them, however I end up with list of all the names which really doesnt help me seperate them at all.

I'm really confused as to how I can iterate over this to pull out these specific lines and then associate them as keys with other specific lines as values. Especially confused as to how I can get the first name as the key then the following names as values and then skip the blank line and start again but with the new key.

Text file Format:

The Format of the text file is exactly like this without the bullets, the desired out put diciotanries would look like this if the just contained the first block:

Person_to_friends = {'Leah Connors' : ['Frank Connors', 'Shawn Patterson', 'John Patterson']} 
Persons_to_networks = {'Leah Connors' : ['Flying Club']}

When I attempted to test your code I recieved an index error

  • Connors, Leah
  • Flying Club
  • Connors, Frank
  • Patterson, Shawn
  • Patterson, John

  • Cosmo, Calvin

  • Sailing buddies
  • Dodge ball group
  • Patterson, Shawn
  • Patterson, Sally

  • Connors, Frank

  • Rowing school
  • Connors, Leah
  • Connors, Robert

Cosmo, Calvin is supposed to be part of the second block and Connors, Frank part of the third with a single space in between blocks. Something is not working. I dont know why it keeps creating a space.

This is what I have so far but I think im really far off.. Please help

def load_profiles(profiles_file, person_to_friends, person_to_networks):
f = open('profiles.txt')
lines = f.readlines()
new = []
line_number = 0
while line_number < len(lines)+1:
    prev_line = lines[line_number-1]
    line = lines[line_number]
    from_line = lines[line_number+1]
    if ',' in line and ',' not in from_line and from_line.isspace() == False:
        key = reverse_name(line)
    elif ',' not in line and line.isspace()==False:
        new.append(line.strip('\n'))
        try:
            person_to_networks[key].append(new)
        except KeyError:
            person_to_networks[key] = [new]            
    elif  line.isspace()== True:
        line_number = from_line
            line_number += 1
2012-04-03 20:30
by crazy99
You might want to try getting the formatting right - Python kinda needs the whitespace. It'll make it easier to help. You also might want to try splitting up your wall of text at the top - it's really hard to read - Gareth Latty 2012-04-03 20:31
please also write the desired ouput format - Ashwini Chaudhary 2012-04-03 20:43
a method starting with __ is supposed to be a private ; - luke14free 2012-04-03 20:59
@luke14free Not strictly true; there are lots of cases for directly referencing __special__ methods. This isn't one of them though - Taymon 2012-04-03 21:09
@Taymon, I perfectly agree, even though under a theoretical standpoint it isn't be a good practice to call anything starting with "_" as it is not covered in the public apis and could change at any time without any notification. ( http://docs.python.org/tutorial/classes.html#private-variables ) however that is not the problem here : - luke14free 2012-04-03 21:17
have you considered using yaml for your files - moooeeeep 2012-04-03 22:09
Is there supposed to be a blank line after the first line in your example data - Nolen Royalty 2012-04-03 22:48
@luke14free Just to be clear: That guideline doesn't apply to identifiers that both start and end with __, which are given special meaning by Python itself, and which programmers are explicitly and strongly discouraged from defining themselves - Taymon 2012-04-03 23:08


2

import itertools
import collections

person_to_networks = collections.defaultdict(set)
person_to_friends = collections.defaultdict(set)

def format_name(name):
    return name.split(',')[1][1:] + ' ' + name.split(',')[0]

with open('exampletext') as f:
    #cheap hack so that we detect the need for a new leader on the first line
    lines = [''] + [line.strip() for line in f]

for line in lines:
    if line == '': 
        new_leader = True
    else:
        if new_leader:
            leader = format_name(line)
            new_leader = False
        else:
            if ',' in line:
                person_to_friends[leader].add(format_name(line))
            else:
                person_to_networks[leader].add(line)

print 'Person to Networks'
for p in person_to_networks:
    print '%s: %r' % (p, [e for e in person_to_networks[p]])

print '\nPerson to Friends'
for p in person_to_friends:
    print '%s: %r' % (p, [e for e in person_to_friends[p]])

Output:

Person to Networks
Frank Connors: ['Rowing school']
Calvin Cosmo: ['Sailing buddies', 'Dodge ball group']
Leah Connors: ['Flying Club']

Person to Friends
Frank Connors: ['Robert Connors', 'Leah Connors']
Calvin Cosmo: ['Sally Patterson', 'Shawn Patterson']
Leah Connors: ['Frank Connors', 'John Patterson', 'Shawn Patterson']

Current "exampletext":

Connors, Leah
Flying Club
Connors, Frank
Patterson, Shawn
Patterson, John

Cosmo, Calvin
Sailing buddies
Dodge ball group
Patterson, Shawn
Patterson, Sally 

Connors, Frank 
Rowing school
Connors, Leah
Connors, Robert
2012-04-04 00:06
by Nolen Royalty
hmm when I run your code I don't seem to be getting the same output as you. Im not sure if if I screwed up the indentation or somethin - crazy99 2012-04-04 02:00
no there isnt suppose to be any single names either both the single names belong to the block below them, for some reason the list function was being a pain on this site a, I dont know why they are seperated in the editor they arent - crazy99 2012-04-04 02:26
the out put is actually not corect though regardless of that, for the personstonetworks we want just the name above the network as the key and the network as the value so block 1and 2would add to the dict like this {'Leah Connors' : ['Flying Club'] 'Calvin Cosmo' : ['Sailing buddies'] - crazy99 2012-04-04 02:31
For persontofriends you want the top name of the block again and then the names under the group as the value. so it would look like this if we did it just to block one {'Leah Connors' : ['Frank Connors', Shawn Patterson, John Patterson'] - crazy99 2012-04-04 02:35
Yeh thats exactly what I was talking about it looks great. Thats quite a bit more advanced than the code design I was working on. Im pretty sure the design I was working on could accomplish it cuz my latest version gets all the keys to Person to Networks correct and has all there corect values but also had duplicates of the corect value and empty list as values, I was thinking this is some kind of and iteration error instead of moving to the next key at the right time my codes seems to keep adding values I'm not actualy even sure why it ever stops adding them lol, does that sound right to you - crazy99 2012-04-04 04:41
The design that I have is totally unnecessary at this point, it only exists to parse the bizarre data that I originally thought you had. I'll whip up a better example - Nolen Royalty 2012-04-04 04:42
Im really new to programming, Im not sure if it was like this for you in the begging but I have literally been sitting at my computer for close to 15 hours just to get my code to where it is and it still doesnt even work... Since im pretty new at this it seems sometimes I get stuck unless someone shows me how to do it, Ill be stuck there for days.. Almost smashing my computer lol... Ushually after its such a simple solution to.(not in this case though lol - crazy99 2012-04-04 04:47
@crazy99 Getting frustrated is totally normal. It takes some serious practice to get good at this kind of stuff. I've posted an example that is nice and simple now that I actually understand the task : - Nolen Royalty 2012-04-04 05:08
Thanks for showing me all this stuff, after seeing the simper code I think I have a pretty good understanding of ho it works. However the complicated version shall remain a mystery for a while. I noticed in the complicated one sometimes you set a variable to a for loop, Thats the first time I've seen something like that. Also I didnt realize you can put so many argumentson to one line, lik - crazy99 2012-04-04 05:36
lines = [e.split(',')[1][1:] + ' ' + e.split(',')[0] if ',' in e else e for e in lines] That one. - crazy99 2012-04-04 05:36
actually in that your setting a variable with if statements and a for loop that are made just to create that variable, am I understanding that corecctly? The formatting is opposite of what Ive been taught so far - crazy99 2012-04-04 05:39
One big part of python is "list comprehensions". I suggest reading up on them, but they allow you to do a lot in one line. For example, I could say powers_of_two = [2**x for x in range(5)] to get a list of [1, 2, 4, 8, 16]. In python, unlike most other languages, you normally use for loops over values in a list/dictionary/whatever instead of over explicit numbers. For example, for num in powers_of_two: would loop over each number in the list that we just made - Nolen Royalty 2012-04-04 05:40
lines = [e.split(',')[1][1:] + ' ' + e.split(',')[0] if ',' in e else e for e in lines] says "for each value in lines, if it contains a comma, do some work on it and add it to the list, if it doesn't just add it to the list how it is. - Nolen Royalty 2012-04-04 05:41
Thanks for all the hel - crazy99 2012-04-04 05:46
@crazy99 not a problem, it was my pleasure. Good luck with future coding - Nolen Royalty 2012-04-04 05:48