我如何编写python方法来生成列表的组合,但也要使用这个添加的约束?

我如何编写python方法来生成列表的组合,但也要使用这个添加的约束?,python,python-2.7,dictionary,Python,Python 2.7,Dictionary,我有一个任意的python字典x,这样每个键的值本身就是一个列表。以下是一个例子: x = {"first_name": ["Habib", "Wen-lao"], "second_name": ["Khan", "Chen"]} 给定x,我想编写一个方法来计算字典列表,这样每个字典都有与x相同的键,但值是单个列表元素的每个组合 此外,我希望看到所有完全忽略键的组合 因此,在这种情况下,结果应该是: [{"first_name": "Habib", "second_name": "Khan"}

我有一个任意的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'}]
但它没有显示省略了键的组合。 我该怎么做

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

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

另一种可能是压缩列表,包括epsilon元素,但编写一个表达式将这些元素从
zip
ped列表的成员中排除


你能从那里得到它吗?

我们首先将字典值列表中的每个名称与其键组合起来,将这些结果保存到
y
列表中。接下来,我们使用
itertools.product
创建所需对的列表
z
。然后我们用
y
中的单个名称扩展
z
。最后,我们向
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.keys()
dict.values()

您只需将
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'}
{}

你不是在几个小时前发布了这个问题吗?FWIW,如果您继续删除并重新发布您的问题,系统将对您进行处罚。你看了上次我链接到你的itertools powerset配方了吗?建议查看库的可能重复并不能解决我的问题。Stack overflow告诉我创建一个新问题来解释为什么我的问题不同,所以我正在这样做。Ajax,这个问题与那个问题有很大的不同。看到我加粗的那部分了吗。@PM2Ring:不仅如此,还可以将dict转换为ordered dict dict dict dict dict dict dict dict dict dict dict dict dict dict dict dict dict dict dict dict dict dict dict dict dict dict dict dict dict dict dict dict dict di使用3个键时,您的方法不再有效。有18个组合与
{“first_name”:[“Habib”,“Wen lao”],“second_name”:[“Khan”,“Chen”],“middle_name”:['K.]}
,您的方法只输出10个。@EricDuminil我明白您的意思。但我想这取决于你如何解释这个问题我不这么认为:
我希望看到所有完全忽略键的组合
字典x可以有任意数量的键和任意名称。
;)@埃里克·杜米尼很公平。但我想我会坚持我的答案,以防万一。:)此外,如果我改变它,它只会是你的复制品。真的。现在我写了一个答案,我想我理解了你的解释,你的描述符合我的代码。