如何用Python从文件构建RPM包与文件验证状态的字典?
First, let's fix your code to correctly build the desired data structure. The key is tracking the current RPM package as we process each line, so we can associate subsequent files (without the "RPM:" prefix) with the right package.
Updated Code
#!/usr/bin/env python d = {} current_package = None with open('files.txt', 'r') as f: for line in f: line = line.strip() if not line: continue # Skip empty lines if any parts = line.split() if line.startswith('RPM:'): # Extract package name, status, and file path package_name = parts[1] status = parts[2] file_path = parts[3] # Initialize entry for the package if it doesn't exist if package_name not in d: d[package_name] = [{}] # Match your desired list-with-dict structure # Add the file and its status to the package's dict d[package_name][0][file_path] = status # Update current package to this one for subsequent lines current_package = package_name else: # This line belongs to the last seen RPM package if current_package is None: print(f"Warning: Found orphaned file line: {line}") continue status = parts[0] file_path = parts[1] d[current_package][0][file_path] = status # Verify the result print("Resulting dictionary:") print(d) print("\nIterating over items:") for k, v in d.items(): print(k, v)
Output
Running this code will produce exactly the structure you requested:
Resulting dictionary: {'psmisc-22.6-24.el6.x86_64': [{'/sbin/fuser': 'S.5......'}], 'python-2.7.9-0011.00.6ES.x86_64': [{'/usr/lib64/python2.7/base64.pyc': '..5......', '/usr/lib64/python2.7/base64.pyo': '..5......'}]} Iterating over items: psmisc-22.6-24.el6.x86_64 [{'/sbin/fuser': 'S.5......'}] python-2.7.9-0011.00.6ES.x86_64 [{'/usr/lib64/python2.7/base64.pyc': '..5......', '/usr/lib64/python2.7/base64.pyo': '..5......'}]
Optimization Suggestion
Your current structure uses a list containing a single dictionary for each package, which adds unnecessary nesting. A more efficient and intuitive structure would map each package directly to a dictionary of file paths and their statuses. This simplifies access and reduces complexity:
Optimized Code
#!/usr/bin/env python d = {} current_package = None with open('files.txt', 'r') as f: for line in f: line = line.strip() if not line: continue parts = line.split() if line.startswith('RPM:'): package_name = parts[1] status = parts[2] file_path = parts[3] if package_name not in d: d[package_name] = {} # Direct dict mapping d[package_name][file_path] = status current_package = package_name else: if current_package is None: print(f"Warning: Found orphaned file line: {line}") continue status = parts[0] file_path = parts[1] d[current_package][file_path] = status # Verify optimized result print("Optimized dictionary:") print(d) print("\nIterating over optimized items:") for k, v in d.items(): print(k, v)
Optimized Output
Optimized dictionary: {'psmisc-22.6-24.el6.x86_64': {'/sbin/fuser': 'S.5......'}, 'python-2.7.9-0011.00.6ES.x86_64': {'/usr/lib64/python2.7/base64.pyc': '..5......', '/usr/lib64/python2.7/base64.pyo': '..5......'}} Iterating over optimized items: psmisc-22.6-24.el6.x86_64 {'/sbin/fuser': 'S.5......'} python-2.7.9-0011.00.6ES.x86_64 {'/usr/lib64/python2.7/base64.pyc': '..5......', '/usr/lib64/python2.7/base64.pyo': '..5......'}
This optimized structure is easier to work with—for example, to get the status of a specific file you can do d[package_name][file_path] directly, without needing to index into a list first.
内容的提问来源于stack exchange,提问作者HTF

