简体   繁体   中英

Remove Items from Combination during Itertools Product

I know this has been asked before, but I can't find a solution that fits my problem:

  • I have a list of people that can appear in six slots (no repeats).
  • I use itertools.product to iterate through them and assign each to a slot. I then skip any combination that does not fit my criteria.
  • To speed it up (it takes forever), I try to pre-trim the lists of people.
  • To further speed it up (this is the key), I want to fully drop people from the list over which I am iterating so that it never has to consider that person again. How do I do that?

Current Code:

for combination in itertools.product(nameList1,nameList2,nameList3,nameList4,nameList5,nameList6):
        nameofPlayer1 = combination[0]
        nameofPlayer2 = combination[1]
        etc.

Then:

if nameofPlayer1 == nameofPlayer2:
            continue
        if nameofPlayer1 == nameofPlayer3:
            continue
        etc.

What I want to do now is:

if timesUsedPlayer1 > xyz:
        #remove Player1 from nameList1, nameList2, etc.

I believe this would speed up the subsequent iterations since, even though the combination would ultimately fail (because I have other triggers for checking how many times someone was used), I can cut out the "check" entirely by having the person excluded from the iteration.

Thanks in advance!

Here is code that shows a way to use permutations() in itertools to generate all possible sequences of 6 names from the list of people mentioned in the question such that a name may get dropped and no longer considered for processing.

numPrints = 0
nameList = [
    "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"
]
dropped = set()
for combination in itertools.permutations(nameList, 6):
    for name in combination:
        # this simulates the condition that would lead to removal of a name from further consideration
        if name in ["b", "c", "d", "e", "f"]:
            dropped.add(name)
    combSet = set(combination)
    if not combSet.isdisjoint(dropped):
        # the combination contains a name that has been dropped, so ignore it
        continue
    # process the combination here
    if numPrints < 10:
        print(f"processing {combination}")
        numPrints += 1
        if numPrints == 10:
            print("etc.")

Output for the above example:

processing ('a', 'g', 'h', 'i', 'j', 'k')
processing ('a', 'g', 'h', 'i', 'k', 'j')
processing ('a', 'g', 'h', 'j', 'i', 'k')
processing ('a', 'g', 'h', 'j', 'k', 'i')
processing ('a', 'g', 'h', 'k', 'i', 'j')
processing ('a', 'g', 'h', 'k', 'j', 'i')
processing ('a', 'g', 'i', 'h', 'j', 'k')
processing ('a', 'g', 'i', 'h', 'k', 'j')
processing ('a', 'g', 'i', 'j', 'h', 'k')
processing ('a', 'g', 'i', 'j', 'k', 'h')
etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM