ruskind
ruskind

Reputation: 227

Zip() an already initialised list

I'm trying to write a function that writes NumPy arrays to a file. I would like to use the Pythonic method of using zip(). The following code does not work; I am trying to convert the **data_lists named arguments (of which the values are 1D NumPy arrays and the keys are simply labels) to the list of arrays as required by the zip function.

def write_data_file(filename,**data_lists):
    with open("{}.dat".format(filename), "w") as f:
        header = "#"        
        for lst in data_lists:
            header = "{} {} \t".format(header,lst)
        header = "{} \n".format(header)
        f.write(header)
        # The following line of code does not work
        for row in zip(data_lists[lst] for lst in data_lists): 
            f.write("\t".join([str(item) for item in row])+ "\n")

I can't assign to a list first as below:

trial = [data_lists[lst] for lst in data_lists]
zip(trial) 

This does nothing as trial is treated as a single argument. How can I get zip() to treat the items in trial individually or otherwise complete this?

Upvotes: 0

Views: 31

Answers (1)

ShadowRanger
ShadowRanger

Reputation: 155363

Change:

zip(data_lists[lst] for lst in data_lists)

to:

zip(*data_lists.values())

That unpacks the values of the data_lists dict into sequential positional arguments. * is known as the "splat" or iterable unpacking operator.

It's a little odd though, since the order of the values is not defined; you'd zip in a different order depending on Python version (and within a version, you'd often zip in different orders from run to run). You're using the iteration order to define the header, so the columns would match the headers every time, but the order of the columns would differ from run to run. You might want to try receiving the headers as a separate argument, followed by the values positionally, e.g.:

def write_data_file(filename, headers, *data_lists):
    if len(headers) != len(data_lists): ... raise Exception for mismatched lengths ...

then you'd just be doing zip(*data_lists) (no .values() call), and getting consistent header ordering.

Upvotes: 2

Related Questions