如何将含多键值对的字典转换为对应位置匹配的字典列表?
Absolutely, this is totally achievable! The core goal here is to pair up corresponding elements from each value list and map them back to their original keys in individual dictionaries—regardless of how many keys you have (s, r, x, y, z, etc.).
Step-by-Step Explanation
- Assumption: We'll start by assuming all the value lists in your input dictionary are the same length (since we're pairing elements by position; if they aren't, we can adjust with tools like
itertools.zip_longest, but we'll stick to matching lengths first). - Transpose the Value Lists: Use
zip(*input_dict.values())to group together the first elements of each list, then the second, and so on. This gives us tuples of corresponding values. - Map Back to Keys: For each tuple of values, pair them with the original dictionary keys and convert the result into a new dictionary.
- Collect into a List: Gather all these individual dictionaries into a single list, which is your desired output.
Code Implementation
Here's a clean function that does exactly what you need:
def binder(input_dict): # Get the list of keys from the input dictionary keys = input_dict.keys() # Transpose the value lists and convert each group to a dictionary return [dict(zip(keys, values)) for values in zip(*input_dict.values())]
If you prefer to pass the key-value pairs directly as keyword arguments (instead of a single dictionary), you can adjust the function to use **kwargs:
def binder(**kwargs): keys = kwargs.keys() return [dict(zip(keys, values)) for values in zip(*kwargs.values())]
Example Usage
Let's test this with your sample data:
# Using the first function (accepts a dictionary) data = {'s': ['si', 'so'], 'r': ['ri', 'ro']} print(binder(data)) # Output: [{'s': 'si', 'r': 'ri'}, {'s': 'so', 'r': 'ro'}] # Using the second function (accepts keyword arguments) print(binder(s=['si', 'so'], r=['ri', 'ro'])) # Output: Same as above!
Handling Extra Keys
This solution works seamlessly for any number of keys. For example:
multi_key_data = {'x': [1, 2], 'y': [3, 4], 'z': [5, 6]} print(binder(multi_key_data)) # Output: [{'x': 1, 'y': 3, 'z': 5}, {'x': 2, 'y': 4, 'z': 6}]
Note on Uneven List Lengths
If your value lists are of different lengths, zip will stop at the shortest list. If you want to include all elements (padding shorter lists with None), you can use itertools.zip_longest:
from itertools import zip_longest def binder_uneven(input_dict): keys = input_dict.keys() return [dict(zip(keys, values)) for values in zip_longest(*input_dict.values())]
内容的提问来源于stack exchange,提问作者Ninja Warrior 11

