杰瑞科技汇

Python permutation如何实现?排列组合怎么用?

Of course! Generating permutations is a common task in Python. Here’s a comprehensive guide covering everything from the built-in methods to manual implementation, with clear explanations and examples.

Python permutation如何实现?排列组合怎么用?-图1
(图片来源网络,侵删)

What is a Permutation?

A permutation is an arrangement of all the members of a set into a particular sequence or order. For a set with n distinct elements, there are n! (n factorial) permutations.

Example: For the set {A, B, C}, the permutations are:

  1. (A, B, C)
  2. (A, C, B)
  3. (B, A, C)
  4. (B, C, A)
  5. (C, A, B)
  6. (C, B, A)

The Easiest Way: Using the itertools Module

Python's built-in itertools module is the most efficient and recommended way to handle permutations. It's fast, memory-efficient, and easy to use.

itertools.permutations(iterable, r=None)

This function returns successive r length permutations of elements in the iterable.

  • iterable: The input sequence (e.g., a list, string, or tuple).
  • r: The length of the permutations. If r is not specified, it defaults to the length of the iterable, meaning it will generate all possible full-length permutations.

The function returns an iterator, which is memory-efficient because it generates permutations one by one as you need them, instead of storing them all in memory at once.

Example 1: All Permutations of a List

import itertools
my_list = ['A', 'B', 'C']
# Generate all permutations of the full list (r is len(my_list) by default)
all_perms = itertools.permutations(my_list)
# The result is an iterator, so we convert it to a list to see all values
print(list(all_perms))

Output:

[('A', 'B', 'C'), ('A', 'C', 'B'), ('B', 'A', 'C'), ('B', 'C', 'A'), ('C', 'A', 'B'), ('C', 'B', 'A')]

Example 2: Permutations of a Specific Length (r)

You can also generate permutations of a shorter length than the original list.

import itertools
my_list = ['A', 'B', 'C', 'D']
# Generate all permutations of length 2
perms_of_length_2 = itertools.permutations(my_list, r=2)
print(f"Permutations of length 2 from {my_list}:")
print(list(perms_of_length_2))

Output:

Permutations of length 2 from ['A', 'B', 'C', 'D']:
[('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'A'), ('B', 'C'), ('B', 'D'), ('C', 'A'), ('C', 'B'), ('C', 'D'), ('D', 'A'), ('D', 'B'), ('D', 'C')]

Notice that ('A', 'B') and ('B', 'A') are both included, as order matters in permutations.

Example 3: Permutations of a String

The iterable can be any iterable, including a string.

import itertools
my_string = "ABC"
# Generate all permutations of the string
string_perms = itertools.permutations(my_string)
# To join the tuples of characters back into strings
perm_strings = [''.join(p) for p in string_perms]
print(perm_strings)

Output:

['ABC', 'ACB', 'BAC', 'BCA', 'CAB', 'CBA']

Manual Implementation (For Learning)

Understanding how to write a permutation function from scratch is a great exercise for learning recursion and backtracking. The most common approach is recursive.

The Recursive Idea

  1. Base Case: If the list of items to permute is empty or has one item, there's only one permutation: the list itself.
  2. Recursive Step:
    • Take the first item from the list.
    • Find all permutations of the rest of the list (this is the recursive call).
    • For each of those smaller permutations, insert the first item you took into every possible position.

Example: permute([1, 2, 3])

  1. Take 1. Recursively find permute([2, 3]) which returns [[2, 3], [3, 2]].
  2. Now, insert 1 into every position of [2, 3]:
    • [1, 2, 3]
    • [2, 1, 3]
    • [2, 3, 1]
  3. Insert 1 into every position of [3, 2]:
    • [1, 3, 2]
    • [3, 1, 2]
    • [3, 2, 1]
  4. Combine all results: [[1, 2, 3], [2, 1, 3], [2, 3, 1], [1, 3, 2], [3, 1, 2], [3, 2, 1]]

Python Code for Recursive Permutation

def find_permutations_recursive(nums):
    """
    Generates all permutations of a list of numbers using recursion.
    """
    # Base case: if the list is empty, there is one permutation: the empty list
    if len(nums) == 0:
        return [[]]
    # List to store the final permutations
    all_perms = []
    # Take the first element
    first_element = nums[0]
    # Get the rest of the list
    rest_of_list = nums[1:]
    # Recursively find all permutations of the rest of the list
    for p in find_permutations_recursive(rest_of_list):
        # Insert the first element into every possible position of each permutation
        for i in range(len(p) + 1):
            new_perm = p[:i] + [first_element] + p[i:]
            all_perms.append(new_perm)
    return all_perms
# --- Example Usage ---
my_numbers = [1, 2, 3]
result = find_permutations_recursive(my_numbers)
print(result)

Output:

[[1, 2, 3], [2, 1, 3], [2, 3, 1], [1, 3, 2], [3, 1, 2], [3, 2, 1]]

Handling Duplicates (Unique Permutations)

What if your input list has duplicate elements? For example, [1, 1, 2]. The standard itertools.permutations will still generate duplicate permutations like (1, 1, 2) and (1, 1, 2).

If you need only the unique permutations, you can use a set to automatically remove the duplicates. Since permutations are tuples (which are hashable), this works perfectly.

Example with itertools and set

import itertools
my_list_with_duplicates = [1, 1, 2]
# itertools.permutations will create duplicates
perms_with_duplicates = itertools.permutations(my_list_with_duplicates)
print("Permutations with duplicates:")
print(list(perms_with_duplicates))
# Output: [(1, 1, 2), (1, 2, 1), (1, 1, 2), (1, 2, 1), (2, 1, 1), (2, 1, 1)]
# Use a set to get only the unique ones
unique_perms = set(itertools.permutations(my_list_with_duplicates))
print("\nUnique permutations:")
print(unique_perms)

Output:

Permutations with duplicates:
[(1, 1, 2), (1, 2, 1), (1, 1, 2), (1, 2, 1), (2, 1, 1), (2, 1, 1)]
Unique permutations:
{(1, 2, 1), (2, 1, 1), (1, 1, 2)}

Summary: Which Method to Use?

Method When to Use Pros Cons
itertools.permutations Almost always. This is the standard, Pythonic way. - Fastest and most memory-efficient.
- Simple to use.
- Part of the standard library.
- Generates duplicates if the input has them.
Manual Recursive For learning purposes, in coding interviews, or if you have very specific, non-standard requirements. - Great for understanding the algorithm.
- Fully customizable.
- Slower and more memory-intensive than itertools.
- More code to write and debug.
itertools + set When you have a list with duplicates and need only the unique permutations. - Simple one-liner to fix a common problem.
- Leverages the power of itertools.
- Slightly less efficient than a dedicated algorithm that avoids generating duplicates in the first place.

For any practical application in Python, always prefer itertools.permutations. Use the manual version only if you need to understand the underlying logic or are in a situation where you can't use standard libraries.

分享:
扫描分享到社交APP
上一篇
下一篇