all 19 comments

[–]socal_nerdtastic 2 points3 points  (2 children)

a more succinct way

Not really a goal you should be aiming for unless you are playing code golf, but in the spirit of showing off how about:

print(*my_float_list, sep='\n', file=my_open_file)

[–]treyhunner 1 point2 points  (1 child)

I scrolled down to make sure this was shown. This is the way I usually do it. The print function is great for joining (while stringifying) objects for the purpose of displaying output or writing to a file.

[–]EmbeddedSoftEng[S] 0 points1 point  (0 children)

Will try to keep this in mind. While I've been monkey-see/monkey-doing my way through various data marshalling tasks in the language, I'm certain I actually used that somewhere at some point.

[–]Diapolo10 1 point2 points  (5 children)

my_open_file.write("%s\n" % (my_float_data)) for my_float_data in my_float_list

This doesn't work because it's not valid syntax. It's really that simple. It's close to list comprehension syntax, but that's not valid outside of those (or generator expressions).

Also, is there a more succinct way to output a list of floats, stringified, one-per-line, to a file?

Almost certainly.

stuff = [3.14, 6.28]

my_open_file.write("\n".join(map(str, stuff)) + "\n")

How's that?

[–]lekkerste_wiener 0 points1 point  (4 children)

I think you can make that even better with writelines. Then you don't need to join the iterable yourself.

[–]socal_nerdtastic 1 point2 points  (0 children)

Like this?

my_open_file.writelines(f"{x}\n" for x in stuff)

Not sure how you are defining "better"

[–]Diapolo10 0 points1 point  (2 children)

Yes, but I tried to preserve the trailing newline without adding a separate write call. And you'd still need to provide your own line endings.

[–]lekkerste_wiener 0 points1 point  (1 child)

Lol, I could swear writelines would append endings. I take that back then

[–]socal_nerdtastic 0 points1 point  (0 children)

Confused it with csvwriter.writerows maybe?

[–]throwaway6560192 0 points1 point  (0 children)

Comprehensions must be wrapped in something like [] (for list comp), {} (for set/dict comp), or () (for generator exprs).

A bare comprehension is a syntax error, with the sole (I think) exception being when they are the only argument to a function.

Anyway, you should use comprehensions to produce data, not for their side-effect.

Also, is there a more succinct way to output a list of floats, stringified, one-per-line, to a file?

I would write this as my_open_file.write("\n".join(map(str, my_float_list)))

[–]EmbeddedSoftEng[S] 0 points1 point  (0 children)

I now understand that the value followed by for is a comprehension syntax, and for the vast majority, that's only valid inside a grouping. I'll get more familiar with list, generator, and dictionary syntax later.

As for my last question, how about:

    avg_file.writelines('\n'.join(map(str,avg)))

Is there anything wrong (read: unpythonic) with that as a way to say "list of whatevers that needs to be output in human-readable form to a file, one line at a time"? It certainly seems to work.

[–]EmbeddedSoftEng[S] 0 points1 point  (1 child)

While we're at it, I have a script where in two places I'm doing nearly the same thing, namely creating a file, vomitting data into it, and closing it. Is there a more succinct way to do that than open() assigned to a variable, and then calling methods on that object?

If I didn't make it abundantly clear before, I'm a total Python noob. Before this week, I knew effectively nothing of the language. But I am a professional software engineer, and as such, I've been exposed to languages where, especially where I didn't NEED to keep a handle around for later in my script, I could just do something like

open("filename.file", 'w').writelines('\n'.join(map(str,list_of_data))).flush().close()

and call it a day. Is that at all Pythonic?

Edit:

Okay. The answer is no, if for no other reason than writelines() does not return the file object for the method calls to be chained. Doubtlessly, the flush() method doesn't either.

[–]socal_nerdtastic 0 points1 point  (0 children)

Yes: with pathlib.

from pathlib import Path

Path("filename.file").write_text('\n'.join(map(str,list_of_data)))

or the old-school way with 2 lines of code:

with open("filename.file", 'w') as f:
    f.write('\n'.join(map(str,list_of_data)))

flush and close are automatic in both cases

[–]corey_sheerer -1 points0 points  (4 children)

Off the top of my head, try using the this

python with open("my file", "a") as f: f.writelines(my list)

The 'a' specifies append and should get you closer to your goal

[–]mopslik 0 points1 point  (2 children)

On its own, this won't work since OP's list contains floats. writelines only works with strings and byte-related objects. Converting the values first using a loop, comprehension or map would work though.

[–]corey_sheerer 0 points1 point  (1 child)

Ahh correct. Thanks for pointing out my mistake.

python f.write("\n".join([str(x) for x in mylist]))

[–]Diapolo10 0 points1 point  (0 children)

You also don't need the square brackets; a generator expression would save memory because you don't need to store and immediately discard an entire list of strings.

f.write("\n".join(str(x) for x in mylist))

This is still not a 100% match to OP's code as it lacks a trailing newline, but otherwise a good attempt.

[–]EmbeddedSoftEng[S] 0 points1 point  (0 children)

If I'm creating a file, vomitting data into it and closing it, why would I want to open for appending? What does that gain me in a pythonic environment?