如何遍历列表字典并将每次迭代与所有键中的一个项目配对?
How do I iterate through a dictionary of lists and pair each iteration with an item from all the keys?
我需要遍历列表字典,不知道字典会有多少列表,但仍然将每个列表值与字典中另一个键生成的任何其他列表值配对(如果存在另一个键) .我有以下代码:
def loop_rec(codes, currentcode={}):
if len(codes.keys())>1:
for key in sorted(codes):
codespop = dict(codes)
loop = codespop.pop(key)
for x in loop:
currentcode[key]=x
loop_rec(codespop,currentcode)
break
else:
for key in codes.keys():
loop = codes[key]
for x in loop:
currentcode[key]=x
print currentcode
所以如果我有以下字典:
codes = {"coarse":range(4),"fine":range(2)}
我得到这个结果:
>>> loop_rec(codes)
{'fine': 0, 'coarse': 0}
{'fine': 1, 'coarse': 0}
{'fine': 0, 'coarse': 1}
{'fine': 1, 'coarse': 1}
{'fine': 0, 'coarse': 2}
{'fine': 1, 'coarse': 2}
{'fine': 0, 'coarse': 3}
{'fine': 1, 'coarse': 3}
这是一种蛮力方法,需要一种更 "Pythonic" 的方法。我到处搜索了很多等效的东西,但大多数方法不会导致每次迭代的粗略值和精细值都在一起。也希望它先通过粗略循环,但排序命令不起作用。
编辑:刚刚意识到排序命令正在运行,只是打印输出没有排序。我不管是不是按顺序打印的
如果我对你的问题的理解正确,你想取所有列表的笛卡尔积,这些列表是字典的值。您可以使用 itertools.product
来完成此操作。
import itertools
def dict_product(d):
list_of_dicts = []
for values in itertools.product(*d.values()):
item = dict(zip(d.keys(),values))
list_of_dicts.append(item)
return list_of_dicts
codes = {"coarse":range(4),"fine":range(2),"zesty":range(3)}
for item in dict_product(codes):
print(item)
结果:
{'zesty': 0, 'fine': 0, 'coarse': 0}
{'zesty': 0, 'fine': 0, 'coarse': 1}
{'zesty': 0, 'fine': 0, 'coarse': 2}
{'zesty': 0, 'fine': 0, 'coarse': 3}
{'zesty': 0, 'fine': 1, 'coarse': 0}
{'zesty': 0, 'fine': 1, 'coarse': 1}
{'zesty': 0, 'fine': 1, 'coarse': 2}
{'zesty': 0, 'fine': 1, 'coarse': 3}
{'zesty': 1, 'fine': 0, 'coarse': 0}
{'zesty': 1, 'fine': 0, 'coarse': 1}
{'zesty': 1, 'fine': 0, 'coarse': 2}
{'zesty': 1, 'fine': 0, 'coarse': 3}
{'zesty': 1, 'fine': 1, 'coarse': 0}
{'zesty': 1, 'fine': 1, 'coarse': 1}
{'zesty': 1, 'fine': 1, 'coarse': 2}
{'zesty': 1, 'fine': 1, 'coarse': 3}
{'zesty': 2, 'fine': 0, 'coarse': 0}
{'zesty': 2, 'fine': 0, 'coarse': 1}
{'zesty': 2, 'fine': 0, 'coarse': 2}
{'zesty': 2, 'fine': 0, 'coarse': 3}
{'zesty': 2, 'fine': 1, 'coarse': 0}
{'zesty': 2, 'fine': 1, 'coarse': 1}
{'zesty': 2, 'fine': 1, 'coarse': 2}
{'zesty': 2, 'fine': 1, 'coarse': 3}
在此示例中,迭代顺序为粗-细-zesty,但不保证此行为。在 CPython 3.6 及更高版本中,字典是有序的,但这是一个实现细节,将来可能会更改。
我需要遍历列表字典,不知道字典会有多少列表,但仍然将每个列表值与字典中另一个键生成的任何其他列表值配对(如果存在另一个键) .我有以下代码:
def loop_rec(codes, currentcode={}):
if len(codes.keys())>1:
for key in sorted(codes):
codespop = dict(codes)
loop = codespop.pop(key)
for x in loop:
currentcode[key]=x
loop_rec(codespop,currentcode)
break
else:
for key in codes.keys():
loop = codes[key]
for x in loop:
currentcode[key]=x
print currentcode
所以如果我有以下字典:
codes = {"coarse":range(4),"fine":range(2)}
我得到这个结果:
>>> loop_rec(codes)
{'fine': 0, 'coarse': 0}
{'fine': 1, 'coarse': 0}
{'fine': 0, 'coarse': 1}
{'fine': 1, 'coarse': 1}
{'fine': 0, 'coarse': 2}
{'fine': 1, 'coarse': 2}
{'fine': 0, 'coarse': 3}
{'fine': 1, 'coarse': 3}
这是一种蛮力方法,需要一种更 "Pythonic" 的方法。我到处搜索了很多等效的东西,但大多数方法不会导致每次迭代的粗略值和精细值都在一起。也希望它先通过粗略循环,但排序命令不起作用。
编辑:刚刚意识到排序命令正在运行,只是打印输出没有排序。我不管是不是按顺序打印的
如果我对你的问题的理解正确,你想取所有列表的笛卡尔积,这些列表是字典的值。您可以使用 itertools.product
来完成此操作。
import itertools
def dict_product(d):
list_of_dicts = []
for values in itertools.product(*d.values()):
item = dict(zip(d.keys(),values))
list_of_dicts.append(item)
return list_of_dicts
codes = {"coarse":range(4),"fine":range(2),"zesty":range(3)}
for item in dict_product(codes):
print(item)
结果:
{'zesty': 0, 'fine': 0, 'coarse': 0}
{'zesty': 0, 'fine': 0, 'coarse': 1}
{'zesty': 0, 'fine': 0, 'coarse': 2}
{'zesty': 0, 'fine': 0, 'coarse': 3}
{'zesty': 0, 'fine': 1, 'coarse': 0}
{'zesty': 0, 'fine': 1, 'coarse': 1}
{'zesty': 0, 'fine': 1, 'coarse': 2}
{'zesty': 0, 'fine': 1, 'coarse': 3}
{'zesty': 1, 'fine': 0, 'coarse': 0}
{'zesty': 1, 'fine': 0, 'coarse': 1}
{'zesty': 1, 'fine': 0, 'coarse': 2}
{'zesty': 1, 'fine': 0, 'coarse': 3}
{'zesty': 1, 'fine': 1, 'coarse': 0}
{'zesty': 1, 'fine': 1, 'coarse': 1}
{'zesty': 1, 'fine': 1, 'coarse': 2}
{'zesty': 1, 'fine': 1, 'coarse': 3}
{'zesty': 2, 'fine': 0, 'coarse': 0}
{'zesty': 2, 'fine': 0, 'coarse': 1}
{'zesty': 2, 'fine': 0, 'coarse': 2}
{'zesty': 2, 'fine': 0, 'coarse': 3}
{'zesty': 2, 'fine': 1, 'coarse': 0}
{'zesty': 2, 'fine': 1, 'coarse': 1}
{'zesty': 2, 'fine': 1, 'coarse': 2}
{'zesty': 2, 'fine': 1, 'coarse': 3}
在此示例中,迭代顺序为粗-细-zesty,但不保证此行为。在 CPython 3.6 及更高版本中,字典是有序的,但这是一个实现细节,将来可能会更改。