from itertools import combinations
for comb in combinations(range(1, 70), 5):
for PB in combinations(range(1, 27), 1):
if PB[0] in range(1, 27):
a = open(f"PowerBall{PB[0]}.txt", "a")
a.write(str(comb + PB))
a.write("\n")
print("\r", f"on: {comb + PB}", end="")
Trying to find all combination for those set of ranges.
-
\$\begingroup\$ The faster speedup: rethink what you're doing because chances are you don't need this and actually just need to get a particular value every time you need it. \$\endgroup\$Simply Beautiful Art– Simply Beautiful Art2022年11月11日 05:53:32 +00:00Commented Nov 11, 2022 at 5:53
-
\$\begingroup\$ I have the same need, I tried to do multi-core or GPU computing, but it was just an idea, it didn't work out yet. \$\endgroup\$Yang Wang– Yang Wang2023年02月12日 08:12:06 +00:00Commented Feb 12, 2023 at 8:12
2 Answers 2
Perhaps open all 26 files. Then generate the combinations just once and write each one to all the files. Use contextlib.ExitStack()
to ensure all the files get closed. Something like this (untested):
from contextlib import ExitStack
from itertools import combinations
with ExitStack() as stack:
files = [stack.enter_context(open(f"PowerBall{i}.txt", "a")) for i in range(1,27)]
for comb in combinations(range(1, 70), 5):
for pb, pb_file in enumerate(files, 1):
print(*comb, pb, file=pb_file, sep=", ")
The files = [...]
list comprehension opens all 26 files and pushes them onto the ExitStack. When the with
statement exits, the __exit__()
method is called on all items on the stack, which for a file causes it to be closed.
- looping over 11238513 items (the number of
range(70)
combinations of length 5) and creating/opening and writing to those file in each operation is expensive. One way to speed that up is to do that asynchronous (eg using theaiofile
functionality in Python). I did a small test usingaiofile
but I got a slower performance compared to your current code... - Switch both for loops. This way, you can create a file once, open it before the inner loop and then write all combinations to that file in one pass. This will save a lot of file open/close operations.
- A small speedup at the cost of some memory might be achieved by creating the file contents in memory and write it to the disk at once. E.g.: create a string with the file contents, append the data to the string. And after the inner (combi) loop, write it to a file. I did a small test doing this, but I didn't get a substantial performance boost from it. Apparently Python handles file writes quite efficiently.
- You don't explicitly close the file handle. Use a
with
context to automatically close the file at the end of thewith
block. Eg:with with open('file_path', 'w') as file:
- the PB for loop doesn’t need
itertools
. Just loop over the range. - you’re using capitals for a variable (PB). By PEP8, variable names in capitals are constants.
- Use meaningful variable names.
combi
anda
not really good variable names. - the if statement is useless. Since PB is looping over that same range, PB[0] will always be in that range.
This results in something like this (check the file output contents; this might not be exactly what you're after, but you get the idea:
for pb in range(1, 27):
with open(f'PowerBall{pb}_sync.txt', 'a') as file:
for comb in combinations(range(1, 70), 5):
file.write(f'{comb}{pb}\non: {comb}{pb}')