1

I've made a few text files that are formatted in the following way:

['number', 'number', 'number']
number
number
number

However, some of my files only contain this:

['number', 'number', 'number']

When I run my current code (seen below) and it encounters files like these, it gives me this error:

Traceback (most recent call last):
  File "product_1digcon1.py", line 879, in <module>
    punch_it()
  File "product_1digcon1.py", line 875, in punch_it
    last()
  File "product_1digcon1.py", line 742, in last
    finale()
  File "product_1digcon1.py", line 775, in finale
    for value, line in zip(values, fh):
TypeError: zip argument #1 must support iteration

I'm trying to modify my code such that, if zip argument #1 does not support iteration, the code should move on to the next file. This is what I've written so far.

def StDev():
    for root, dirs, files in os.walk('/Users/Bashe/Desktop/12/'):
        file = os.path.join(root, "Graph_StDev.txt")
        file_name_out = os.path.join(root,"StDev.txt")
        test = []
        if os.path.exists(os.path.join(root,"Graph_StDev.txt")):
            with open(file) as th, open(file_name_out,"w") as fh_out:
                    first_line = th.readline()
                    values = eval(first_line)
                        test.append(values)
                        test1 = str(test)
                        try:
                        float(test1)
                        if True:
                            for value, line in zip(values, th):
                                first_column = line.strip()
                                fh_out.write("%s\n" % (first_column))
                        except ValueError:
                            pass

Any Help would be appreciated.

1
  • 2
    as posted, your indentation is wrong. you mixed tabs and spaces. Commented Dec 3, 2013 at 3:36

2 Answers 2

1

You can check if the object supports iteration by using the hasattr function, which will check for the magic method iter. Basically, it will return a bool about whether or not the object supports iteration, so if it does not, you will not iterate it. Here is an example of your code, modified to not do anything to an iterable:

if hasattr(values,"__iter__"):                   #this checks if values is iterable
    for value, line in zip(values, th):
        first_column = line.strip()
        fh_out.write("%s\n" % (first_column))
else:
    pass    #if you want to do anything if the object does not support iteration, do it here

This should be what you want, and it is cleaner and more concise than exceptions handling.

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

4 Comments

You need quotes around __iter__ since the second argument of hasattr takes a string. Also, not all iterators have an __iter__ method (check strings, for example).
Whoops yeah the iter is a string I'll edit that. As for iteration in strings, you could also check the type using type() to avoid use of exceptions, though this may be tedious.
Or just try/catch. Python is duck-typed after all.
Try catch is certainly the simplest way, but it is often good to avoid them, as you are typically trying to test for something like iteration, and not trying to handle all conceivable errors of a certain type in this way. For something like this, avoiding try and catch can become complicated, but if this is a large program it may be best to write it without too much error handling when not necessary.
0

Instead of if True try:

if values and th:
    for value, line in zip(values, th):
        first_column = line.strip()
        fh_out.write("%s\n" % (first_column))

Comments

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.