编写Python脚本:从主目录300个子目录各随机提取一张图片至新文件夹
Solution: Select One Random Image Per Top-Level Subdirectory
Got it, let's solve this problem exactly as you need it—we'll target each of your 300 top-level subdirectories individually, grab a random image from each (including all their nested subdirectories), and copy them to a new folder without conflicts.
Step-by-Step Explanation
Here's the breakdown of what we'll do:
- Isolate your 300 top-level subdirectories: We'll only grab direct children of your master directory, not all nested folders.
- Recursively collect images per subdirectory: For each top-level folder, we'll search every nested subfolder for
.jpeg,.png, or.jpgfiles. - Randomly select one image: Pick a single random image from the collected list for each subdirectory.
- Copy to target folder safely: Handle duplicate filenames to avoid overwriting files, and ensure the target folder exists.
Full Working Script
import os import random import shutil # Configure your paths here MASTER_DIRECTORY = "/path/to/your/master/directory" TARGET_FOLDER = "/path/to/your/new/target/folder" # Create target folder if it doesn't exist (no error if it does) os.makedirs(TARGET_FOLDER, exist_ok=True) # Get ONLY the top-level subdirectories (your 300 folders) top_level_subdirs = [ os.path.join(MASTER_DIRECTORY, subdir_name) for subdir_name in os.listdir(MASTER_DIRECTORY) if os.path.isdir(os.path.join(MASTER_DIRECTORY, subdir_name)) ] # Process each top-level subdirectory for index, subdir_path in enumerate(top_level_subdirs, start=1): # Collect all valid images in this subdirectory (and its nested folders) image_paths = [] for root, _, files in os.walk(subdir_path): for file in files: # Check for image extensions (case-insensitive to catch .JPEG/.PNG) if file.lower().endswith((".jpeg", ".png", ".jpg")): image_paths.append(os.path.join(root, file)) # Skip if no images found in this subdirectory if not image_paths: print(f"⚠️ Warning: No images found in {subdir_path} — skipping this folder.") continue # Pick one random image from the list selected_image = random.choice(image_paths) # Handle duplicate filenames (use subdirectory name as prefix to avoid overwrites) subdir_name = os.path.basename(subdir_path) original_filename = os.path.basename(selected_image) target_filename = f"{subdir_name}_{original_filename}" target_path = os.path.join(TARGET_FOLDER, target_filename) # Copy the image to the target folder (preserves file metadata like timestamps) shutil.copy2(selected_image, target_path) print(f"✅ Copied: {selected_image} → {target_path}") print("\n🎉 All done! Your 300 random images are in the target folder.")
Key Details to Note
- Case-insensitive extension check: Using
file.lower()ensures we catch images with uppercase extensions like.JPEGor.PNGthat might otherwise be missed. - Filename conflict prevention: By prepending the subdirectory name to the original filename, we avoid overwriting files that share the same name across different folders. If you prefer, you can replace this with a sequential number (e.g.,
1_photo.jpg,2_photo.jpg) by usingf"{index}_{original_filename}"instead. - Metadata preservation:
shutil.copy2is used instead ofshutil.copyto keep important file metadata (like creation/modification times) intact. - Error handling: We check if a subdirectory has no images and skip it with a warning, so your script won't crash unexpectedly.
内容的提问来源于stack exchange,提问作者heroZero
相关产品推荐
相关产品推荐

