如何用Python列表推导式生成连续偶数子列表
Nice question! Using list comprehensions to replace basic loops is a fantastic way to refine your Python skills, and this problem is a fun one because it requires tracking consecutive sequences—something that feels tricky at first with list comprehensions since they’re typically stateless.
The Cleanest Approach: Combine itertools.groupby with List Comprehensions
While a pure list comprehension alone isn’t the most intuitive here (since we need to track when even sequences start/end), pairing it with itertools.groupby makes this trivial. Here’s how it works:
First, we use groupby to cluster consecutive elements based on whether they’re even. Then we filter out the odd clusters and convert the remaining even groups into lists using a list comprehension.
import itertools my_list = [2, 3, 5, 7, 8, 9, 10, 12, 14, 15, 17, 25, 31, 32] desired_output = [list(group) for is_even, group in itertools.groupby(my_list, key=lambda x: x % 2 == 0) if is_even] print(desired_output) # Output: [[2], [8], [10, 12, 14], [32]]
Breakdown:
itertools.groupby(my_list, key=lambda x: x % 2 == 0): Groups consecutive elements where the key (even/odd status) is the same. So all consecutive evens form one group, consecutive odds form another.- The list comprehension iterates over each (key, group) pair:
if is_even: We only keep groups where the key isTrue(i.e., even numbers).list(group): Converts the group iterator into a sublist of evens.
Pure List Comprehension (No External Libraries)
If you want to avoid itertools and use a pure list comprehension (note: this relies on side effects, which isn’t the intended use of list comprehensions, but it works), you can track the current even group with an auxiliary list:
my_list = [2, 3, 5, 7, 8, 9, 10, 12, 14, 15, 17, 25, 31, 32] result = [] # This list comprehension uses side effects to build our groups [ (result.append([num]) if not num % 2 and (not result or result[-1][-1] % 2) else result[-1].append(num) if not num % 2 else None) for num in my_list ] desired_output = result print(desired_output) # Output: [[2], [8], [10, 12, 14], [32]]
Breakdown:
- We use a ternary inside the comprehension to decide what to do with each number:
- If the number is even and either
resultis empty or the last element in the last group is odd (meaning we’re starting a new even sequence), we append a new sublist containing the number toresult. - If the number is even and we’re already in an even sequence, we add it to the last sublist in
result. - If the number is odd, we do nothing (
None).
- If the number is even and either
That said, the itertools approach is far more readable and aligns with Python’s "batteries included" philosophy—definitely the way to go for production code!
内容的提问来源于stack exchange,提问作者Shaken_not_stirred.

