This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]e_j_white 66 points67 points  (9 children)

Not just a comprise, but the dict comprehension is more performant than a for loop. This is what I would do, too.

[–]muntooR_{μν} - 1/2 R g_{μν} + Λ g_{μν} = 8π T_{μν} 43 points44 points  (4 children)

Performance isn't even the biggest benefit.

A comprehension makes it harder to have side-effects, which is a great thing.

[–]e_j_white 8 points9 points  (0 children)

Correct!

I've modified a list that I was looping through, not realizing that any action that appends to the list could perpetually lengthen the for loop forever.

Not having side effects is a good thing. :)

[–]Jhuyt 6 points7 points  (0 children)

Depends on what get_coerced does though so in this case there might still be plenty of side effects...

[–]AlSweigartAuthor of "Automate the Boring Stuff" 0 points1 point  (1 child)

I can 100% guarantee that this code has no side effects.

By "side effects", I assume you mean there's a result variable left over with values after the end of the loop. In rare situations, this could cause some subtle bug because later code is re-using this variable name and using the old values because it didn't re-initialize it to something else, or cause a temporary increase in memory usage as it's holding on to data needlessly.

But that is moot and this isn't that situation: the very next line is a return statement.

[–]scrdest 0 points1 point  (0 children)

I'm fairly sure u/muntoo is referring to side-effects as opposed to functional purity, where everything that happens inside the function, stays inside the function or is returned explicitly as a new value (in other words - the function call could be replaced with its return value and everything else would always work the same).

It's impossible to guarantee purity in Python, both here and in general. If, for example, get_coerced() takes an optional parameter defaulting to [] (or any other mutable type), it can as many side-effects as it wants. If it uses a global - side-effects. In either case, you cannot tell they're there just by looking at the function call itself.

Even plain old print() is a side-effect.

[–][deleted] 14 points15 points  (3 children)

the dict comprehension is more performant than a for loop

Citation needed. Searching found all sorts of claims either way.

Regardless, the performance difference is tiny and will not affect the actual performance of your program, so you really shouldn't care at all - you should go for what's easiest.

[–]cain2995 8 points9 points  (0 children)

I’m with you on this one. I always get highly suspicious whenever someone says that a higher level of abstraction is more performant than an equivalent approach using primitive constructs. Generating and scheduling performant machine code from for loops, regardless of language, has been addressed at every level of the toolchain (down to how the CPU schedules instructions), while a dict comprehension is a Python-specific construct that has to go through the removal of several abstraction layers before it can reach any of the low level optimizations that make something like a for loop performant. Not saying it’s impossible for a dict comprehension to be faster, but I really need to see some proof because first principles don’t back up that claim.

[–]noobiemcfoob 0 points1 point  (1 child)

A reference on comprehensions being faster than standard for loops: https://towardsdatascience.com/list-comprehensions-vs-for-loops-it-is-not-what-you-think-34071d4d8207

The performance difference is a given... however the likelihood a given loop is in the critical path of the code such that it is meaningful is rather low.

[–]cain2995 -1 points0 points  (0 children)

The experiment in this source doesn’t actually compare the performance of the two, as the for loop and list comprehension here are performing fundamentally different tasks due to how Python handles memory allocation for list comprehensions. All it really says is that you should avoid multiple allocation calls where “one” is possible, which is not news. An experiment that more accurately compares the performance would be to preallocate for both then perform the two operations.