2015-12-15 2 views
-2

У меня есть pythondict, который имеет следующий формат:Эффективный способ петли через python dict?

for (itemA, itemB) in items.keys(): 
    Do_something_with(itemA, itemB) 

itemA имеет много itemB «S, связанные с ним, но он не является детерминированным. Например, один экземпляр 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) 

Я могу прийти с некоторыми способами сделать это, которые ужасно дороги вычислительно, но я чувствую, что есть более питонический и/или эффективный способ сделать это. Вот ужасно дорогой метод

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) 

но я знаю, что это довольно ужасно.

+0

Значит, ключи являются кортежами? –

+1

Что случилось с 'for (itemA, itemB) в items.keys()'? (Помимо ненужных круглых скобок и вызова 'keys'.) – user2357112

+3

предоставьте [MCVE] (http://stackoverflow.com/help/mcve) – Pynchia

ответ

0

Вы могли бы сделать что-то вроде:

for itemA in dict: 
    for itemB in dict[itemA]: 
     thing += finction_on(itemA, itemB) 

Это будет цикл через все ключи словаря и все элементы на этих ключей.

0

Вы можете использовать sorted и 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) 
0

Здесь возможны варианты:

  • Используйте itertools.groupby сгруппировать связанные ключи:

    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) 
    
  • подобный подход, без использования itertools.group_by, чтобы открыть группам себя

    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) 
    
0

Похоже, вы просто используете неправильную структуру данных, вы действительно хотите Dict из dicts так что вы можете сделать что-то вроде этого:

for itemA in dictOfDicts: 
    thing = 0 
    for itemB in dictOfDicts[itemA]: 
     value = dictOfDicts[itemA][itemB] 
     thing += fun(itemA, itemB, value) 
    save(thing) 

Вы можете легко получить Dict из dicts от вашу текущую структуру данных, выполнив что-то вроде этого:

dictOfDicts = {} 
for (itemA, itemB) in items: 
    if itemA not in dictOfDicts: 
     dictOfDicts[itemA] = {} 
    dictOfDicts[itemA][itemB] = items[itemA, itemB] 
Смежные вопросы