【问题标题】:Comparison of value items in a dictionary and counting matches字典中值项的比较和计数匹配
【发布时间】:2015-11-19 20:23:21
【问题描述】:

我正在使用 Python 2.7。 我正在尝试比较字典中的值项。

我有两个问题。 首先是长度为 1 的字典中的值的迭代。我总是得到一个错误,因为 python 不迭代整数并且单个项目作为值是 python 的整数。 我试图将项目更改为字符串。我试图将整个字典更改为字符串。在这些情况下,迭代也会比较逗号和括号,但这不是目的。因此我复制了该项目。 key:1 和 key:4 中的值是同一个项目,两次。这个解决方案有效,但它自然会改变一点结果。

第二个问题是匹配计数不能正常工作。 是的,因为第一个问题,但还有另一个问题。 我的代码将所有值项与字典中的所有其他值项进行比较。不比较相同的模块。如果比较中有一个匹配,则没有问题。 但是,如果比较有两个匹配项,则代码将两次输出结果作为一个匹配项。但我只想要一个结果,有两场比赛。 代码中包含很多cmets,希望大家能看懂。

    #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 开始。 我试图解决问题并寻找解决方案,但我没有找到这个案例。

loop on a dictionary (previous values) python

How to access previous/next element while for looping?

Count items in dictionary

我想解决方案必须看起来像下一个代码。
我用#->

标记我的建议
#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

【问题讨论】:

  • 您将值存储为元组而不是列表是否有原因?
  • 一句话,你想达到什么目的?
  • @Casey:我使用元组,因为我需要命名我的模数/值。元组是获取值和键的最简单方法。 @Padraic:我想实现所有模块项目之间的比较。我有一个大的 csv 文件,我想分析关于相同项目的所有模值。

标签: python for-loop dictionary counting


【解决方案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() 允许您获取字典中项目的键和值,或者如果您正在遍历列表,则可以获取迭代次数和值。

关于迭代单个项目的问题。 Tuples are weird,尤其是单品。您需要尾随逗号,否则它不是元组,而是一个 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...

code

【讨论】:

  • 您的解决方案没有修复元组问题中的单个值,并且您对为什么不允许使用单个值循环元组的解释不包括元组。
  • 元组中的单个值没有问题。 OP 试图使用整数作为值进行循环。
  • 对不起,我没有说清楚。我认为 OP 的问题是试图循环这样的事情:tup=(1) 认为他正在制作一个长度为 1 的元组,然后尝试循环它,就像你想要一个长度为 1 的列表一样。很难知道 OP 的困惑从何而来,因为在他开始做古怪的“重复值”之前,我们看不到他在做什么。
  • 另外我认为 5 对 6 应该是 3 场比赛:两个 10 和一个 11
  • 我会亲自建立一个这样的字典,以方便自己:dict = {'row1dict': { 'col1name': 'col1val', 'col2name': 'col2val' }, 'row2dict': { 'col1name': 'col1val', 'col2name': 'col2val' } # ... }
猜你喜欢
  • 2018-10-24
  • 2015-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多