Lou
Lou

Reputation: 1163

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.

Upvotes: 0

Views: 364

Answers (1)

Morgan Thrapp
Morgan Thrapp

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

Related Questions