我如何编写python方法来生成列表的组合,而且还要使用这个附加的约束?

2024-09-29 07:33:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个任意的python字典x,这样每个键的值本身就是一个列表。举个例子:

x = {"first_name": ["Habib", "Wen-lao"], "second_name": ["Khan", "Chen"]}

给定x,我想编写一个计算字典列表的方法,这样每个字典都有与x相同的键,但值是单个列表元素的每个组合。你知道吗

此外,我希望看到所有完全省略键的组合。你知道吗

所以在这种情况下,结果应该是:

[{"first_name": "Habib", "second_name": "Khan"}, 
 {"first_name": "Habib", "second_name": "Chen"}, 
 {"first_name": "Habib"}, 
 {"first_name": "Wen-lao", "second_name": "Khan"}, 
 {"first_name": "Wen-lao", "second_name": "Chen"}
 {"first_name": "Wen-lao"},
 {"second_name": "Khan"}, 
 {"second_name": "Chen"},
 {}]

我该怎么做?字典x可以有任意数量的键和任意名称。结果列表的顺序与我无关。你知道吗

目前我有:

>>> from collections import OrderedDict
>>> from itertools import product
>>> 
>>> def looper(in_dict):
>>>     order_of_keys = in_dict.keys()
>>>     list_of_tuples = [(key, in_dict[key]) for key in order_of_keys]
>>>     ordered_dict = OrderedDict(list_of_tuples)
>>>     return [dict(zip(ordered_dict.keys(), t)) for t in product(*ordered_dict.values())]
>>> 
>>> x = {"first_name": ["Habib", "Wen-lao"], "second_name": ["Khan", "Chen"]}
>>> print looper(in_dict=x)
[{'first_name': 'Habib', 'second_name': 'Khan'}, 
 {'first_name': 'Habib', 'second_name': 'Chen'}, 
 {'first_name': 'Wen-lao', 'second_name': 'Khan'}, 
 {'first_name': 'Wen-lao', 'second_name': 'Chen'}]

但它没有显示省略了键的组合。 我该怎么做?你知道吗

编辑: 这个question是相关的,但本质上是不同的。在那里,我想知道如何创建所有列表的简单组合。在这里我想知道如何也包括组合键省略。你知道吗


Tags: ofnamein列表字典keysdict省略
3条回答

itertools不处理集合中的epsilon元素;您需要在每个集合中将其作为单独的子句进行编码。对于每个集合,添加一个关键元素,例如epsilon: None;在理解表达式中,需要添加if子句来忽略任何此类元素,而不是将其包含在输出中。请注意,zip将不再提供服务,因为您希望生成不同长度的条目。你知道吗

另一种可能性是压缩列表,包括epsilon元素,但是编写一个表达式将这些元素从zipped列表的成员中排除。你知道吗

你能从那里拿走吗?你知道吗

我们首先将字典值列表中的每个名称与其键组合起来,将这些结果保存到y列表中。接下来,我们使用itertools.product创建所需对的列表z。然后我们用来自y的单个名称扩展z。最后,我们将一个空dict添加到z

from itertools import product

x = {"first_name": ["Habib", "Wen-lao"], "second_name": ["Khan", "Chen"]}
y = [[(k, u) for u in v] for k, v in x.items()]
z = [dict(t) for t in product(*y)]
z.extend({k: v} for u in y for k, v in u)
z.append({})

for row in z:
    print(row)

输出

{'first_name': 'Habib', 'second_name': 'Khan'}
{'first_name': 'Habib', 'second_name': 'Chen'}
{'first_name': 'Wen-lao', 'second_name': 'Khan'}
{'first_name': 'Wen-lao', 'second_name': 'Chen'}
{'first_name': 'Habib'}
{'first_name': 'Wen-lao'}
{'second_name': 'Khan'}
{'second_name': 'Chen'}
{}

如果x列表包含2个以上的项,并且每个x值列表中的子列表包含2个以上的项,则此代码将给出正确的结果。你知道吗

我尽量少写些改动。因为你从一个无序的dict开始,把它转换成一个有序的dict不会带来任何东西。不过,您可以确定dict.keys()dict.values()are in the same order。你知道吗

您只需将None添加到每个值列表中,并删除值为None的对:

from itertools import product

def looper(in_dict):
    keys = in_dict.keys()
    values = [l + [None] for l in in_dict.values()]
    return [{k: v for k,v in zip(keys, t) if v} for t in product(*values)]

x = {"first_name": ["Habib", "Wen-lao"], "second_name": ["Khan", "Chen"]} 
for d in looper(x):
    print(d)

它输出:

{'first_name': 'Habib', 'second_name': 'Khan'}
{'first_name': 'Habib', 'second_name': 'Chen'}
{'first_name': 'Habib'}
{'first_name': 'Wen-lao', 'second_name': 'Khan'}
{'first_name': 'Wen-lao', 'second_name': 'Chen'}
{'first_name': 'Wen-lao'}
{'second_name': 'Khan'}
{'second_name': 'Chen'}
{}

相关问题 更多 >