我有以下问题:我想提供一个简单的函数,它遍历参数集列表并对所有集执行相同的操作。这个想法是将标量值或任何可迭代对象作为 kwarg 传递给函数,然后函数生成每组 kwargs,然后对它们调用操作。
def simple_function(**kwargs):
list_of_kwargs = convert_kwargs(kwargs)
return [my_action(**kwargs_set) for kwargs_set in list_of_kwargs]
因此,我发现很难将 convert_kwargs
实现为高效和通用的。我需要完成的一些示例测试用例:
class ConvertParamsTestCase(unittest.TestCase):
def test_convert_kwargs_no_list(self):
kwargs = {'arg1': 1, 'arg2': "string", 'arg3': None}
self.assertDictEqual(kwargs, convert_kwargs(kwargs))
def test_convert_kwargs_all_lists(self):
kwargs = {'arg1': [1, 2], 'arg2': ["string", "str"], 'arg3': [None, None]}
expected = [{'arg1': 1, 'arg2': "string", 'arg3': None}, {'arg1': 2, 'arg2': "str", 'arg3': None}]
self.assertListEqual(expected, convert_kwargs(kwargs))
def test_convert_kwargs_one_is_string(self):
kwargs = {'arg1': [1, 2], 'arg2': "string", 'arg3': [None, None]}
expected = [{'arg1': 1, 'arg2': "string", 'arg3': None}, {'arg1': 2, 'arg2': "string", 'arg3': None}]
self.assertListEqual(expected, convert_kwargs(kwargs))
def test_convert_kwargs_one_is_iterator(self):
kwargs = {'arg1': range(1, 3), 'arg2': "string", 'arg3': [None, None]}
expected = [{'arg1': 1, 'arg2': "string", 'arg3': None}, {'arg1': 2, 'arg2': "string", 'arg3': None}]
self.assertListEqual(expected, convert_kwargs(kwargs))
我已经检查过但没有成功: list of dicts to/from dict of lists
我的主要问题是:
- 字符串是可迭代的
- 我不能仅通过计算来检查生成器的长度
如果有任何想法,我将不胜感激!
最佳答案
您可以检查字符串并为它们做一些不同的事情:
if isinstance(something,str):
do_thing_with_string(something)
else:
do_thing_with_iterable(something)
而且您不应该能够检查生成器的长度:
def gen():
i = 0
while True:
yield i
i+=1
endless = gen()
for _ in range(20):
print(next(endless)) # works ... while len(endless) won't
您可以将其用作起始 block 。代码获取一个字典,查找其中最长的列表并从中创建一组字典。您需要对其进行增强以使用列表列表。如果你给一个字符串,它会出现在任何列表中:
def convert(paramdict):
l = []
# lists ordered by lenght, longest first, strings in the back
params = sorted(paramdict.items(),
key=lambda x:len(x[1]) if isinstance(x[1],list) else -1,
reverse=True)
# max number of inner dicts to create
maxone = len(params[0][1]) if isinstance(params[0][1],list) else 1
for n_th in range(maxone):
l.append({})
for k,value in params:
if isinstance(value,list):
if len(value) > n_th:
l[-1][k] = value[n_th]
# add other things here: tuple, set, generator
# it might be easiest to convert f.e. set/tuple to list
# for generator you would need to takewhile() from it until
# you got as much as you need
else:
l[-1][k] = value
return l
print(convert( {'arg1': [1, 2], 'arg2': ["string", "str", "s"],
'arg3': [None, None], 'arg4': "some lengthy strings"} ) )
输出:
[{'arg2': 'string', 'arg1': 1, 'arg3': None, 'arg4': 'some lengthy strings'},
{'arg2': 'str', 'arg1': 2, 'arg3': None, 'arg4': 'some lengthy strings'},
{'arg2': 's', 'arg4': 'some lengthy strings'}]
如果列表太短,它会从输出字典中丢失。在声明“相等性”时,您仍然需要处理排序,以防此算法确实以不同的顺序创建内部字典。
关于python - 如何将字典转换为 Python 中的字典列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54821907/