user99264 user99264 - 6 months ago 19
Python Question

Python TypeError issue 'int' not iterable using list with chain

I'm running into an odd error in Python. I am using the

chain
command to flatten out an array of data and then the
list
command to put it back into an array. However, depending on how I define the array, it gives me an error. What I would like is something like this

import os, io, struct, array
from itertools import chain


#Open file and set the size of the data for use later
file=open('filePath','rb')
size = os.fstat(file.fileno()).st_size
count = int(size)

#Initializing an array with length to match the data
dataArray=[0]*count


#storing the values of data 4 bytes at a time to produce the numeric values.
for i in range(0,count,4):
dataArray[i]=struct.unpack('i', file.read(4))

#Deals with a tuple issue ((x,),(y,),...) -> (x,y,...)
dataArray = list(chain(*dataArray[:count]))


This gives me
TypeError: 'int' object is not iterable
from that last line. However, if I say something like

count = 33638664
myarray=[0]*count


for i in range(3638664):
myarray[i]=struct.unpack('i', file.read(4))


result = list(chain(*myarray[:3638664]))


I receive no such error. Notice that in this second piece of code, the value in the chain method, 3638664, is smaller than
count
. It will produce an error if I set it to length
count
. Is this some sort of indexing or counting issue? I'm not sure why I am getting this kind of error for my original code and not for this arbitrary
count
value code.

Answer

You're unpacking dataArray with *dataArray[:count]. This causes chain to try to iterate over each element of dataArray, but it can't, because (as the error says), it can't iterate over an integer. So, when it hits an element of dataArray that's an int instead of a tuple, it breaks.

You're also doing some very weird stuff with the initial loop to read in the file. There's no reason to preinitialize the list like that. You can just do this, and it'll do the same thing. I also don't understand why you're truncating to count length, when at most, there's count/4 entries.

import os, io, struct, array
from itertools import chain


#Open file and set the size of the data for use later
file=open('file','rb')
size = os.fstat(file.fileno()).st_size
count = int(size)
data_array = [struct.unpack('i', file.read(4)) for _ in range(0,count,4)]

#Deals with a tuple issue ((x,),(y,),...) -> (x,y,...)
data_array = list(chain(*data_array))
print(data_array)

There's also no good reason to use chain here. Your format string for struct.unpack will always return one item, so you can just do dataArray = [struct.unpack('i', file.read(4))[0] for _ in range(0,count,4)].

Finally, there's no reason to do count = int(size). size is already an int. So, the final simplified code would look like this:

import os
import struct

file=open('file','rb')
size = os.fstat(file.fileno()).st_size
dataArray = [struct.unpack('i', file.read(4))[0] for _ in range(0,size,4)]
print(dataArray)