Python 3.6中基于采购量的鞋品加权平均价格计算优化问询
Got it, let's fix that rigid, hardcoded code you're working with! The problem here is obvious—your current implementation only works for exactly 4 items, which won't cut it when you have 20+ price/quantity pairs to handle. Let's build a dynamic, scalable solution that works no matter how many items you have, while keeping your core logic intact (buying lowest-priced stock first, calculating weighted average and max purchase price).
Core Logic Recap
We need to:
- Buy as much as possible from the lowest-priced stock first, then move to the next, until we hit our target purchase amount.
- Calculate the weighted average price of all purchased stock.
- Track the highest price we had to pay for any of the purchased batches.
Option 1: Pure Python (No External Dependencies)
This version uses native Python, making it easy to read and run without extra libraries:
def calculate_purchase_metrics(list_prices, list_amounts, buy_amount): # Basic input validation to catch errors early if len(list_prices) != len(list_amounts): raise ValueError("Prices and amounts lists must have the same length") if buy_amount <= 0: raise ValueError("Purchase amount must be a positive number") total_available = sum(list_amounts) if buy_amount > total_available: raise ValueError(f"Insufficient stock: Only {total_available} units available, requested {buy_amount}") # Calculate cumulative stock amounts to find which batches we need cumulative_stock = [] current_total = 0 for amt in list_amounts: current_total += amt cumulative_stock.append(current_total) if current_total >= buy_amount: break # Stop once we've covered our purchase need # Determine the last batch we'll need to dip into last_batch_idx = len(cumulative_stock) - 1 # Calculate how much we buy from each batch purchase_quantities = [] for i in range(last_batch_idx): purchase_quantities.append(list_amounts[i]) # Take full batch # For the last batch, take only what's needed to reach buy_amount previous_total = cumulative_stock[last_batch_idx - 1] if last_batch_idx > 0 else 0 purchase_quantities.append(buy_amount - previous_total) # Compute weighted average price total_cost = sum(price * qty for price, qty in zip(list_prices[:last_batch_idx+1], purchase_quantities)) avg_price = total_cost / buy_amount # Highest price is the price of the last batch we used high_price = list_prices[last_batch_idx] return avg_price, high_price # Test with your sample data list_prices = [12, 12.7, 13.5, 14.3] list_amounts = [85, 100, 30, 54] buy_amount = 200 avg, high = calculate_purchase_metrics(list_prices, list_amounts, buy_amount) print(f"Weighted Average Price: {avg:.2f}") print(f"Highest Purchase Price: {high}")
Option 2: NumPy Version (For Larger Datasets)
If you're working with very large lists (20+ items or more), NumPy will be more efficient. This version maintains your original use of np.average:
import numpy as np def calculate_purchase_metrics_np(list_prices, list_amounts, buy_amount): # Convert lists to NumPy arrays for easier calculations prices = np.array(list_prices, dtype=np.float64) amounts = np.array(list_amounts, dtype=np.int64) # Input validation if prices.shape != amounts.shape: raise ValueError("Prices and amounts arrays must match in length") if buy_amount <= 0: raise ValueError("Purchase amount must be positive") total_available = amounts.sum() if buy_amount > total_available: raise ValueError(f"Insufficient stock: Only {total_available} units available, requested {buy_amount}") # Calculate cumulative stock using NumPy's cumsum cumulative_stock = np.cumsum(amounts) # Find the first batch where cumulative stock meets or exceeds our target last_batch_idx = np.argmax(cumulative_stock >= buy_amount) # Build the weights array (actual quantities we buy from each batch) weights = amounts.copy() if last_batch_idx > 0: # Adjust the last batch to only take what's needed weights[last_batch_idx] = buy_amount - cumulative_stock[last_batch_idx - 1] # Truncate the array to only include batches we use weights = weights[:last_batch_idx+1] else: # If we only need part of the first batch weights[0] = buy_amount # Compute weighted average and highest price avg_price = np.average(prices[:last_batch_idx+1], weights=weights) high_price = prices[last_batch_idx] return avg_price, high_price # Test with your sample data list_prices = [12, 12.7, 13.5, 14.3] list_amounts = [85, 100, 30, 54] buy_amount = 200 avg, high = calculate_purchase_metrics_np(list_prices, list_amounts, buy_amount) print(f"Weighted Average Price: {avg:.2f}") print(f"Highest Purchase Price: {high}")
Key Improvements Over Your Original Code
- Scalability: Works with any number of price/quantity pairs (20+, 100+, whatever you need).
- Input Validation: Catches common errors (mismatched list lengths, invalid purchase amounts, insufficient stock) before they cause bugs.
- Maintainability: No hardcoded checks for 2, 3, or 4 batches—logic adapts dynamically to your input data.
内容的提问来源于stack exchange,提问作者Cennnn

