Reputation: 1163
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.
Upvotes: 0
Views: 364
Reputation: 9986
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)]
.
You should also be using with
to do file handling.
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
with open('file','rb') as file:
size = os.fstat(file.fileno()).st_size
dataArray = [struct.unpack('i', file.read(4))[0] for _ in range(0,size,4)]
print(dataArray)
Upvotes: 1