0

I have a text file like the following:

#some_line
    @another_line
        original_string1|new_string1
#some_other_line
    @and_another_line
        original_string2|new_string2

I want to be able to associate every line with an @ to the preceding line with a #. I cannot seem to figure out a strategy to achieve this in python.

Here is my current code:

    with open(self.file, 'r') as f:
        for i, line in enumerate(f):
            line = line.strip(' \t\n\r')
            if '#' in line[:1]:
                self.parent[i] = line[1:]
            if '@' in line[:1]:
                self.child[i] = line[1:]
            if '|' in line:
                key, value = line.split('|')
                self.strings[key] = value

I need to be able to reference each parent entry and associate the child entries with it. The lines with a '|' also need to be associated with the parent as well.

6
  • 2
    First, '#' in line[:1] is very odd. Why not just line[0] == '#' or, even better, line.startswith('#')? Are you trying to check something more complicated than that? Commented Aug 13, 2013 at 3:22
  • Meanwhile… in your data, is there always exactly one @ line for each # line? If so, your code should build parent and child lists that match things up properly. Is that not working? Or do you just not know how to build a mapping out of two parallel lists? Commented Aug 13, 2013 at 3:24
  • @abarnert: I could use those. Thanks for the suggestion. The basic idea is the just symbolize that line as a line that holds some 'parent' data. Commented Aug 13, 2013 at 3:24
  • There can be multiple @ lines after a #. Commented Aug 13, 2013 at 3:25
  • Ah, OK. I think there's enough to answer now. Let me try, and tell me if I got it right. Commented Aug 13, 2013 at 3:26

2 Answers 2

1

I think what you want is a mapping from child strings to parent strings. Or maybe you want a mapping from child strings and parent strings back to line numbers.

So here's what I'll do: build those mappings from strings to line numbers (I'm assuming each one is unique, but it should be easy to fix if not), and also build a mapping from child line numbers to parent line numbers. If you actually needed the string-to-string mapping, or anything else, you should be able to figure it out from this.

The strings-to-line-numbers part is trivial, but for the child-to-parent part, we need to keep track of the last parent line number we've seen.

child_lines, parent_lines, child_parents = {}. {}. {}
last_parent_line = None
with open(self.file) as f:
    for i, line in enumerate(f):
        line = line.strip(' \t\n\r')
        marker, value = line[0], line[1:]
        if marker == '#':
            parent_lines[value] = i
            last_parent_line = i
        elif marker == '@':
            child_lines[value] = i
            child_parents[i] = last_parent_line

That's it.

Sign up to request clarification or add additional context in comments.

1 Comment

Perfect...I would need string to string reference but I can figure that out. Thanks for showing me how to map things. Appreciate it!
0

This should do the work:

with open(self.file, 'r') as f:
    self.result = {}

    for line in f.readlines():
        line = line.strip()

        if line.startswith("#"):
            parent = line[1:]
            self.result[parent] = {}

        if line.startswith("@"):
            child = line[1:]
            self.result[parent][child] = {}

        if '|' in line:
            key, value = line.split('|')
            self.result[parent][child][key] = value

Then

print self.result
>>> {
    'some_other_line': {
        'and_another_line': {
            'original_string2': 'new_string2'
        }
    },
    'some_line': {
        'another_line': {
            'original_string1': 'new_string1'
        }
    }
}

1 Comment

I think he needs to be able to look up the parent for any given key. This won't do that. But I could be wrong about what he wants…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.