There are a few different errors in your code. The one that's causing your Exception is that your function data
writes into a global variable and doesn't return anything, but your later code expects it to return something iterable, such as a sequence or generator.
You could fix this either by making the top-level code iterate directly on the global dictionary, or you could get rid of the global and create the dictionary within data
and return it at the end. I suggest the latter, since global variables are hard to deal with as your code gets more complicated.
Here's a rough outline of how that should work (I'm leaving the middle part sketchy, since I'll discuss it later):
def data(file):
objects = {}
# add stuff to objects dict
return objects
Your next error is with stripping your lines. Your code currently tests each line for inequality with its own strip
method. This is an error in Python 3, since line
and line.strip
have incomparable types. But even if it worked, it would be meaningless. I suspect you were trying to eliminate empty lines, by stripping them first and rejecting any that are empty afterwards. Here's how you can do that:
if not line.strip():
continue
This is an example of what some people in the Python community call "look before you leap" (LBYL) programming style, since you're checking for something that may be a problem before it becomes one. An alternative is the "easier to ask forgiveness than permission" (EAFP) style where you simply wrap the area where the trouble might emerge in a try
block and catch the exceptions that are generated. EAFP-style is sometimes considered more "Pythonic", so I'll show that style a bit later.
The next error is a logical one, not something that will cause an error. You're splitting your line and you want to get the two parts of it into the variables key
and value
. However, you're doing two separate assignments to those variables, and in fact they're ending up with the same value in each. This is a place you get to use a cool feature of Python syntax, unpacking. Instead of assigning each variable separately, you can assign a two-valued sequence (such as a list or tuple) to both of them together. Python will take care of giving the first value to the first variable and the second value to the second variable. Here's what it looks like:
key, value = line.split(":")
This will fail if there's no colon in the line of course, so it's a good place for us to put a try
block if we're using the EAFP-style of coding. Here's one way to do it:
try:
key, value = line.split(":")
except ValueError:
continue
You could instead put the try
block around everything that remains in the loop, then let the except
block contain only pass
(which does nothing, but ignores the exception).
Finally, the last logical error you have has to do with how you build your nested dictionaries. Your current approach is to first build a single dictionary with all the keys and values from your file, then split them up into separate pieces, one per celestial object. However, this doesn't work if the keys for each object are the same. Since each object has an "Orbital Radius" key, for instance, they're all going to be writing over each other putting that key into the single dictionary.
@sudo_o's answer shows how to build the inner dictionary and fill it with values (it is almost identical to what I was going to write). I just wanted to post the rest of my explanations!