0
\$\begingroup\$
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.

\$\endgroup\$
2
  • \$\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\$ Commented 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
    Commented Feb 12, 2023 at 8:12

2 Answers 2

0
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$
  • 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 the aiofile functionality in Python). I did a small test using aiofile 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 the with 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 and a 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}')
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.