通过python dict循环的有效方法?

通过python dict循环的有效方法?,python,performance,dictionary,Python,Performance,Dictionary,我有一个pythondict,其格式如下: for (itemA, itemB) in items.keys(): Do_something_with(itemA, itemB) itemA有许多与之关联的itemB,但它是不确定的。例如,itemA的一个实例可能有10个itemB,但是itemA的另一个实例可能只有1个 我想在数组中循环如下: thing = 0 for (itemA, ~) in items.keys()[0]: for itemB in all_items

我有一个
python
dict
,其格式如下:

for (itemA, itemB) in items.keys():
    Do_something_with(itemA, itemB)
itemA
有许多与之关联的
itemB
,但它是不确定的。例如,
itemA
的一个实例可能有10个
itemB
,但是
itemA
的另一个实例可能只有1个

我想在数组中循环如下:

thing = 0
for (itemA, ~) in items.keys()[0]:
    for itemB in all_items_associated_with(itemA):
        thing += function_on(itemA, itemB)
for itemA in dict:
    for itemB in dict[itemA]:
        thing += finction_on(itemA, itemB)
我可以想出一些在计算上非常昂贵的方法来实现这一点,但我觉得有一种更具python风格和/或效率的方法来实现这一点。这是一种非常昂贵的方法

thing = 0
itemAs = find_all_itemAs(items)
for itemA in itemAs:
    for (itemAtmp, itemB) in items.keys():
        if( itemAtmp == itemA ):
            thing += function_on(itemA, itemB)

但我知道那很可怕。

你可以做如下事情:

thing = 0
for (itemA, ~) in items.keys()[0]:
    for itemB in all_items_associated_with(itemA):
        thing += function_on(itemA, itemB)
for itemA in dict:
    for itemB in dict[itemA]:
        thing += finction_on(itemA, itemB)

这将遍历字典的所有键以及这些键处的所有项。

您可以使用
排序的
itertools.groupby
将相关项有效地分组在一起

keys = sorted(items.keys())
for itemA, it in itertools.groupby(keys, lambda x: x[0]):
    for _, itemB in it:
        thing += function_on(itemA, itemB)

以下是可能的替代方案:

  • 用于对相关键进行分组:

    for itm_a, group in itertools.groupby(sorted(dict), lambda itm_a, itm_b: itm_a):
        # now we can process everything that has the same first item
        my_thing = sum([function_on(itm_a, itm_b) for _, itm_b in group], 0)
    
  • 一个类似的方法,不使用,是自己发现组

    groups = {}
    for itm_a, itm_b in dict:
        groups.setdefault(itm_a, []).append(itm_b)
    
    # now we can process all of the related keys together
    for itm_a, all_itm_b in groups.items():
        # do something
        my_thing = sum([function_on(itm_a, itm_b) for itm_b in all_itm_b], 0)
    

听起来你只是使用了错误的数据结构,你真的想要一个dict的dict,所以你可以这样做:

for itemA in dictOfDicts:
    thing = 0
    for itemB in dictOfDicts[itemA]:
        value = dictOfDicts[itemA][itemB]
        thing += fun(itemA, itemB, value)
    save(thing)
dictOfDicts = {}
for (itemA, itemB) in items:
    if itemA not in dictOfDicts:
        dictOfDicts[itemA] = {}
    dictOfDicts[itemA][itemB] = items[itemA, itemB]
通过执行以下操作,您可以轻松地从当前数据结构中获取dict的dict:

for itemA in dictOfDicts:
    thing = 0
    for itemB in dictOfDicts[itemA]:
        value = dictOfDicts[itemA][itemB]
        thing += fun(itemA, itemB, value)
    save(thing)
dictOfDicts = {}
for (itemA, itemB) in items:
    if itemA not in dictOfDicts:
        dictOfDicts[itemA] = {}
    dictOfDicts[itemA][itemB] = items[itemA, itemB]

items.keys()中(itemA,itemB)的
有什么问题?(除了不必要的括号和
keys
调用之外。)请提供一个问题,这是一个应该发布在code review上的问题,因为这是一个合作式的评论类型的问题。不要使用
.keys()
只是迭代一个dict。在Python2上,它会停止并生成一个列表,只是为了迭代<代码>对于items中的(itemA,itemB):
会很好地工作。感觉items应该是dict of dict。是否有理由将键耦合到一个元组中?