Reputation: 227
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
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