杰瑞科技汇

Python senumerate是什么?怎么用?

Of course! The senumerate function is a fantastic tool from the popular more-itertools library. It's a powerful combination of Python's built-in sorted() and enumerate() functions.

Python senumerate是什么?怎么用?-图1
(图片来源网络,侵删)

Let's break it down.

The Problem: Why do we need senumerate?

Imagine you have a list of items, but you need to iterate over them in a specific sorted order. At the same time, you also need the index of each item in the original, unsorted list.

Example Scenario: You have a list of student names and their scores:

students = [
    ('Charlie', 88),
    ('Alice', 95),
    ('Bob', 82),
    ('Diana', 91)
]

Your goal is to:

Python senumerate是什么?怎么用?-图2
(图片来源网络,侵删)
  1. Process the students in order of their scores, from highest to lowest.
  2. For each student, know their original position (index) in the list.

A naive approach might look like this:

# 1. Sort the list by score
sorted_students = sorted(students, key=lambda x: x[1], reverse=True)
# 2. Iterate and manually keep track of the original index
print("Processing students by score (highest to first):")
for i, student in enumerate(sorted_students):
    # Now we have to find the original index for each student
    original_index = students.index(student)
    print(f"Original Index: {original_index}, Student: {student[0]}, Score: {student[1]}")

Output:

Processing students by score (highest to first):
Original Index: 1, Student: Alice, Score: 95
Original Index: 3, Student: Diana, Score: 91
Original Index: 0, Student: Charlie, Score: 88
Original Index: 2, Student: Bob, Score: 82

This works, but it's inefficient. The students.index(student) call has to scan the list for every single item, making it an O(n²) operation. It's also a bit clunky.


The Solution: more_itertools.senumerate

senumerate solves this elegantly and efficiently. It takes an iterable and a sorting key, then returns an iterator that yields (original_index, item) pairs, with the items yielded in sorted order.

Python senumerate是什么?怎么用?-图3
(图片来源网络,侵删)

How to Install more-itertools

First, if you don't have the library installed, you can get it via pip:

pip install more-itertools

How to Use senumerate

The signature is more_itertools.senumerate(iterable, key=None). It's very similar to enumerate() and sorted().

Let's redo our student example with senumerate:

import more_itertools
students = [
    ('Charlie', 88),  # index 0
    ('Alice', 95),   # index 1
    ('Bob', 82),     # index 2
    ('Diana', 91)    # index 3
]
# The key tells senumerate HOW to sort the items
# We want to sort by the score, which is the second element (index 1) of each tuple.
key_func = lambda student: student[1]
print("Processing students with senumerate:")
for original_index, student in more_itertools.senumerate(students, key=key_func):
    print(f"Original Index: {original_index}, Student: {student[0]}, Score: {student[1]}")

Output:

Processing students with senumerate:
Original Index: 1, Student: Alice, Score: 95
Original Index: 3, Student: Diana, Score: 91
Original Index: 0, Student: Charlie, Score: 88
Original Index: 2, Student: Bob, Score: 82

As you can see, the output is identical, but the code is much cleaner and more efficient. senumerate does all the heavy lifting of sorting and tracking the original indices in a single, optimized pass (typically O(n log n)).


In-Depth Explanation and Use Cases

Let's look at more examples to solidify your understanding.

Example 1: Simple List of Strings

Sort a list of words alphabetically, but keep track of their original positions.

import more_itertools
words = ["zebra", "apple", "mango", "banana"]
print("Words sorted alphabetically:")
for original_index, word in more_itertools.senumerate(words):
    print(f"Original Index: {original_index}, Sorted Word: {word}")
# To sort in reverse order:
print("\nWords sorted in reverse:")
for original_index, word in more_itertools.senumerate(words, key=lambda s: s, reverse=True):
    print(f"Original Index: {original_index}, Sorted Word: {word}")

Output:

Words sorted alphabetically:
Original Index: 1, Sorted Word: apple
Original Index: 3, Sorted Word: banana
Original Index: 2, Sorted Word: mango
Original Index: 0, Sorted Word: zebra
Words sorted in reverse:
Original Index: 0, Sorted Word: zebra
Original Index: 2, Sorted Word: mango
Original Index: 3, Sorted Word: banana
Original Index: 1, Sorted Word: apple

Example 2: Sorting a List of Dictionaries

This is a very common use case. You have a list of dictionaries and want to sort by a specific key.

import more_itertools
products = [
    {'name': 'Laptop', 'price': 1200},
    {'name': 'Mouse', 'price': 25},
    {'name': 'Keyboard', 'price': 75},
    {'name': 'Monitor', 'price': 300}
]
print("Products sorted by price (cheapest first):")
for original_index, product in more_itertools.senumerate(products, key=lambda p: p['price']):
    print(f"Original Index: {original_index}, Product: {product['name']}, Price: ${product['price']}")

Output:

Products sorted by price (cheapest first):
Original Index: 1, Product: Mouse, Price: $25
Original Index: 2, Product: Keyboard, Price: $75
Original Index: 3, Product: Monitor, Price: $300
Original Index: 0, Product: Laptop, Price: $1200

Example 3: Using senumerate to Build a New Sorted List

What if you don't just want to print, but you want to create a new list of dictionaries that includes the original index? senumerate is perfect for this.

import more_itertools
products = [
    {'name': 'Laptop', 'price': 1200},
    {'name': 'Mouse', 'price': 25},
    {'name': 'Keyboard', 'price': 75},
    {'name': 'Monitor', 'price': 300}
]
# Create a new list where each item has its original index
ranked_products = [
    {'original_index': original_index, 'name': product['name'], 'price': product['price']}
    for original_index, product in more_itertools.senumerate(products, key=lambda p: p['price'])
]
import pprint
pprint.pprint(ranked_products)

Output:

[{'name': 'Mouse', 'original_index': 1, 'price': 25},
 {'name': 'Keyboard', 'original_index': 2, 'price': 75},
 {'name': 'Monitor', 'original_index': 3, 'price': 300},
 {'name': 'Laptop', 'original_index': 0, 'price': 1200}]

Summary: enumerate vs. senumerate

Feature enumerate(iterable) more_itertools.senumerate(iterable, key=None)
Purpose Iterates and provides (index, item) pairs. Iterates and provides (original_index, item) pairs, in sorted order.
Order Items are yielded in their original order. Items are yielded based on the key function.
Index The index is the position in the current iteration. The index is the position in the original, unsorted iterable.
Efficiency O(n) O(n log n) due to the sorting step.
Dependencies Built-in (no installation needed). Requires pip install more-itertools.
Best For Simple iteration where order doesn't matter. When you need to process items in a sorted order but also need their original location.
分享:
扫描分享到社交APP
上一篇
下一篇