如何使用itertools Permutation仅返回以PAN开头的特定排列组合
Hey there! Let's figure out how to fix your code so it only outputs permutations starting with PAN.
问题分析
Your current code combines the initial route ([0], which maps to PAN) with the remaining port indices, then generates all permutations of that combined list. That's why you're seeing results that don't start with PAN—itertools.permutations shuffles every element, including the first one, which breaks your requirement.
快速修复:筛选符合条件的排列
If you want to keep using your existing code structure, you can add a simple check to only print permutations where the first element is 0 (PAN's index):
import itertools portnames = ["PAN", "AMS", "CAS", "NYC", "HEL"] def permutations(route, ports): sum_list = route + ports perms = list(itertools.permutations(sum_list)) for perm in perms: # Only keep permutations starting with 0 (PAN) if perm[0] == 0: output = [portnames[item] for item in perm] print(output) permutations([0], list(range(1, len(portnames))))
更高效的方案:直接生成符合要求的排列
Generating all permutations and then filtering is unnecessary. Since we know the first element must be PAN (0), we only need to generate permutations of the remaining ports and prepend 0 to each result. This is faster and cleaner:
import itertools portnames = ["PAN", "AMS", "CAS", "NYC", "HEL"] def permutations(start_idx, remaining_ports): # Generate all permutations of the remaining ports for perm in itertools.permutations(remaining_ports): # Build the full route starting with PAN full_route = [start_idx] + list(perm) # Convert indices to port names port_route = [portnames[idx] for idx in full_route] print(port_route) # Start with PAN (index 0), pass the rest of the port indices permutations(0, list(range(1, len(portnames))))
递归实现(如果需要递归逻辑)
If you intended to use recursion (since your function is named permutations and mentions recursion), here's a recursive version that naturally builds routes starting with PAN:
portnames = ["PAN", "AMS", "CAS", "NYC", "HEL"] def permutations(current_route, remaining_ports): # Base case: no ports left to add, print the completed route if not remaining_ports: print([portnames[idx] for idx in current_route]) return # Iterate over each remaining port, add it to the route, and recurse for i in range(len(remaining_ports)): next_port = remaining_ports[i] # Create a new list of remaining ports without the current one new_remaining = remaining_ports[:i] + remaining_ports[i+1:] permutations(current_route + [next_port], new_remaining) # Start with PAN (index 0) as the first element of the route permutations([0], list(range(1, len(portnames))))
This recursive approach builds valid routes step by step: it starts with [0], then adds each remaining port one by one, recursively processing the leftover ports until the route is complete. All results will automatically start with PAN.
内容的提问来源于stack exchange,提问作者Daniel

