Сравнение элементов значения в словаре и подсчет совпадений

Я использую Python 2.7. Я пытаюсь сравнить элементы значения в словаре.

У меня две проблемы. Во-первых, это итерация значений в словаре с длиной 1. Я всегда получаю сообщение об ошибке, потому что python не выполняет итерацию целых чисел, а один элемент в качестве значения является целым числом для python. Я попытался изменить элемент на строку. Я попытался изменить весь словарь на строку. В этих случаях итерация также сравнивает запятые и скобки, и это не цель. Поэтому я продублировал статью. Значения в key:1 и key:4 являются одним и тем же элементом два раза. Это решение работает, но, естественно, немного меняет результаты.

Вторая проблема заключается в том, что подсчет матчей работает некорректно. Да, из-за первой проблемы, но есть еще одна. Мой код сравнивает все элементы значений со всеми другими элементами значений в словаре. Одинаковые модули не сравниваются. Если в сравнении есть одно совпадение, проблем нет. Но если в сравнении было два совпадения, код выведет результат два раза как одно совпадение. Но мне нужен только один результат с двумя совпадениями. Код содержит много комментариев, поэтому я надеюсь, что вы его понимаете.

    #dicModul is a dictionary with the modulnames(keys of dictionary) and the components of the modul(value of dictionary).
# If a modul consists of one component, it is impossible to iterate the modul, therefore this component is two times in a modul.
# Any ideas how to iterate a single value item in a dictionary?
dicModul = {0:(0,1),1:(1,1), 2:(2,3,4,5,6,1,7,2), 
          3:(8,1),4:(9,9), 5:(10,10,5,11,0,12,13), 6:(10,11,9,7)}
#The list is needed for the iteration and to operate the different modul in the dictionary by following for loops.
ModulList = [0,1,2,3,4,5,6] 
#Counter is needed for counting same components in different moduls.
Counter = 0
for modKey in ModulList: #For-loop is needed for iteration of keys
    for modKey2 in ModulList: #2nd for-loop of Modulkeys.The components of moduls have to be checked for matches in other moduls.
                              #Therefore a second iteration of the modul list is needed.
        if modKey == modKey2: #Same moduls do not have to be checked.
            print "Skip same Moduls" 
            Counter  = 0     #The modkey2 have to changed by iteration. The counter have to be reset.
        elif modKey != modKey2: #Different moduls have to be checked.
                for modVal in dicModul[modKey]:  #Iteration of components for iterated modul.
                    if modVal in dicModul[modKey2]: #Checking iterated components in different modul
                        Counter = Counter + 1  #If component was in different moduls, counter will add +1
                        print "Modul: "+str(modKey)+" % Modul: "+str(modKey2)+ " Matches= "+str(Counter) 
                        #print function for both moduls and number of same components 
                        Counter =0

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

цикл по словарю (предыдущие значения) python

Как получить доступ к предыдущему/следующему элементу во время цикла?

Подсчет элементов в словаре

Думаю, решение должно выглядеть как следующий код.
Я помечаю свое предложение знаком #->

#dicModul is a dictionary with the modulnames(keys of dictionary) and the components of the modul(value of dictionary).
# If a modul consists of one component, it is impossible to iterate the modul, therefore this component is two times in a modul.
# Any ideas how to iterate a single value item in a dictionary?
dicModul = {0:(0,1),1:(1,1), 2:(2,3,4,5,6,1,7,2), 
          3:(8,1),4:(9,9), 5:(10,10,5,11,0,12,13), 6:(10,11,9,7)}
#The list is needed for the iteration and to operate the different modul in the dictionary by following for loops.
ModulList = [0,1,2,3,4,5,6] 
#Counter is needed for counting same components in different moduls.
Counter = 0
for modKey in ModulList: #For-loop is needed for iteration of keys
    for modKey2 in ModulList: #2nd for-loop of Modulkeys.The components of moduls have to be checked for matches in other moduls.
                              #Therefore a second iteration of the modul list is needed.
        if modKey == modKey2: #Same moduls do not have to be checked.
            print "Skip same Moduls" 
            Counter  = 0     #The modkey2 have to changed by iteration. The counter have to be reset  
        elif modKey != modKey2: #Different moduls have to be checked.
                for modVal in dicModul[modKey]:  #Iteration of components for iterated modul.
                    if modVal in dicModul[modKey2]: #Checking iterated components in different modul
                #->     if modKey2 == previous modKey2: #Checking if is the previous modul, so counter is not reset.
                #->           Counter = Counter +1 
                #->           print "Modul: "+str(modKey)+" % Modul: "+str(modKey2)+ " Matches= "+str(Counter) 
                #->     else:
                #->        Counter = 1   #Counter is setted 1, because a same component is found in a different modul.
                    elif:
                        Counter = 0

Это мое ожидаемое решение

Modul   Modul   Matches
skip same modul     
0   1   1
0   2   1
0   3   1
0   4   0
0   5   1
skip same modul     
1   2   1
1   3   1
1   4   0
1   5   0
skip same modul     
2   3   1
2   4   0
2   5   1
2   6   1
skip same modul     
3   4   0
3   5   0
skip same modul     
4   5   0
4   6   1
skip same modul     
5   6   3

person David Kos    schedule 19.11.2015    source источник
comment
Есть ли причина, по которой вы храните свои значения в виде кортежей, а не списков?   -  person Casey P    schedule 19.11.2015
comment
Одним словом, чего вы пытаетесь достичь?   -  person Padraic Cunningham    schedule 20.11.2015
comment
@ Кейси: я использую кортежи, потому что мне нужно назвать свои модули/значения. Кортежи — это самый простой способ получить значение и ключ. @Padraic: я хочу добиться сравнения всех элементов модуля. У меня есть большой CSV-файл, и я хочу проанализировать все значения модуля в отношении одних и тех же элементов.   -  person David Kos    schedule 22.11.2015


Ответы (1)


Я бы порекомендовал вам взглянуть на циклы for и на то, как они работают. Codeacademy — отличная (бесплатная) интерактивный ресурс. Я не уверен на 100%, что понимаю, о чем вы спрашиваете, поэтому я в основном исхожу из заголовка вашего вопроса. Думаю, я понимаю, что ты пытаешься сделать, но если я это сделаю, ты сильно усложнишь себе задачу.

Итерация словаря с одним элементом:

dicty = {'a': 1}    
for key in dicty:
    print key

Перебор значений и ключей в словарях:

for key, val in dicty.iteritems():
    print key
    print val

что эквивалентно:

for key in stuff:
    val = stuff[key]
    print key
    print val

Подсчет (ключевых) совпадений в двух словарях:

count = 0
keys_counted = []

dicty_a = {'key1': 'val1', 'key2': 'val2'}
dicty_b = {'key1': 'val1', 'keyB': 'valB'}
for keyA, valA in dicty_a.iteritems():
    for keyB, valB in dicty_b.iteritems():
        if keyB == keyA and keyA not in keys_counted:
            count += 1
            keys_counted.append(valA)

Самый распространенный способ убедиться, что вы не дублируете проверку, — это создать список, проверить его, а затем выкинуть в конце. Например:

list_printed = []
for x in range(5):
    for y in range(5):
        if [x, y] not in list_printed:
            print x, y
            list_printed.append([y,x])

выходы:

0 0
0 1
0 2
0 3
0 4
1 1
1 2
1 3
1 4
2 2
2 3
2 4
3 3
3 4
4 4

Enumerate() позволяет вам получать как ключи, так и значения элементов в вашем словаре или номер итерации и значение, если вы перебираете список.

Что касается вашей проблемы с перебором отдельных элементов. Кортежи — это странно, особенно с отдельными элементами. Вам нужна запятая в конце или это не кортеж, это int. Честно говоря, это кажется мне ошибкой, а не функцией, но оптимистично, это, вероятно, важно по какой-то причине компьютерных наук, которая выходит далеко за рамки моей зарплаты. Кроме того, большое отличие списков [] от кортежей () состоит в том, что кортежи неизменяемы. В этом случае вам, вероятно, не нужно использовать кортежи. Сказав это, вы получили свою ошибку только потому, что, как вы сказали, вы не можете перебрать целое число:

loopy = (1,)
for x in loopy:
    print x # this will _not_ raise an error

loopy = (1)
for x in loopy:
    print x # this _will_ raise an error

loopy = [1]
for x in loopy:
    print x # this will _not_ raise an error

loopy = 1
for x in loopy:
    print x # this _will_ raise an error

Применив это к тому, что вы пытаетесь сделать:

dicModul = {0:(0,1),1:(1,1), 2:(2,3,4,5,6,1,7,2), 
          3:(8,1),4:(9,9), 5:(10,10,5,11,0,12,13), 6:(10,11,9,7)}

keys_checked = []

def get_tuple_matches(t1, t2):
    counter = 0
    matched_list = []
    for x in t1:
        for y in t2:
            stuff = [x, y]
            if stuff not in matched_list and x == y:
                counter +=1
                matched_list.append(stuff)
    return counter

for key_outerloop, val_outerloop in dicModul.iteritems():
    for key_innerloop, val_innerloop in dicModul.iteritems():
        if key_outerloop == key_innerloop:
            print "skip..."
        elif [key_innerloop, key_outerloop] not in keys_checked:
            matches = get_tuple_matches(val_outerloop, val_innerloop)
            keys_checked.append([key_outerloop, key_innerloop])
            print "Modul: " + str(key_outerloop) + " | Modul: " + str(key_innerloop) + " | Matches= "+ str(matches)

выход:

skip...
Modul: 0 | Modul: 1 | Matches= 1
Modul: 0 | Modul: 2 | Matches= 1
Modul: 0 | Modul: 3 | Matches= 1
Modul: 0 | Modul: 4 | Matches= 0
Modul: 0 | Modul: 5 | Matches= 1
Modul: 0 | Modul: 6 | Matches= 0
skip...
Modul: 1 | Modul: 2 | Matches= 1
Modul: 1 | Modul: 3 | Matches= 1
Modul: 1 | Modul: 4 | Matches= 0
Modul: 1 | Modul: 5 | Matches= 0
Modul: 1 | Modul: 6 | Matches= 0
skip...
Modul: 2 | Modul: 3 | Matches= 1
Modul: 2 | Modul: 4 | Matches= 0
Modul: 2 | Modul: 5 | Matches= 1
Modul: 2 | Modul: 6 | Matches= 1
skip...
Modul: 3 | Modul: 4 | Matches= 0
Modul: 3 | Modul: 5 | Matches= 0
Modul: 3 | Modul: 6 | Matches= 0
skip...
Modul: 4 | Modul: 5 | Matches= 0
Modul: 4 | Modul: 6 | Matches= 1
skip...
Modul: 5 | Modul: 6 | Matches= 2
skip...

код

person NotAnAmbiTurner    schedule 19.11.2015
comment
ваше решение не устранило проблему с одним значением в кортеже, а ваше объяснение того, почему не допускается перебор кортежей с одиночными значениями, не включает кортежи. - person Casey P; 20.11.2015
comment
Нет проблем с одиночными значениями в кортежах. OP пытался зациклить, используя целое число в качестве значения. - person NotAnAmbiTurner; 20.11.2015
comment
Извините, я не был ясен. Я предположил, что проблема OP заключалась в попытке зациклиться на чем-то вроде этого: tup=(1) думал, что он создает кортеж длины один, а затем пытается перебрать его, как вы делаете это со списком длины один. Трудно понять, откуда взялось замешательство ОП, потому что мы не видим, что он делал до того, как начал делать шаткое дублирование значения. - person Casey P; 21.11.2015
comment
Также я думаю, что 5 против 6 должно состоять из 3 матчей: двух 10 и 11. - person Casey P; 21.11.2015
comment
Прошу прощения за отсутствие навыков программирования. Im новичок, и я пытаюсь решить проблему в экономике. Спасибо NotAnAmbiTurner за решение, идея с дополнительным списком отличная. Я использую кортежи, потому что у меня есть большой файл csv, и он разделен на два столбца: первый модуль и второй элемент модуля. Поэтому я создаю кортеж, потому что это лучший способ определить модуль и элементы модуля. Это лучший известный мне способ, но я не так много знаю в программировании, знаете ли. Неважно, что кортежи неизменяемы. Мне не нужно менять его позже. - person David Kos; 22.11.2015
comment
Я пытаюсь зациклить одно целое число как значение, потому что это самый простой способ создать кортеж из моего большого CSV-файла. Если я использую строку в качестве значения, будет довольно сложно запрограммировать сравнение, потому что запятые и скобки также будут проверены. Есть еще идеи по решению проблемы? - person David Kos; 22.11.2015
comment
Я бы лично создал такой словарь, чтобы облегчить себе задачу: dict = {'row1dict': { 'col1name': 'col1val', 'col2name': 'col2val' }, 'row2dict': { 'col1name': 'col1val', 'col2name': 'col2val' } # ... } - person NotAnAmbiTurner; 23.11.2015