我尝试迭代dict时出错:它显示不支持的操作数类型

时间:2015-03-15 17:08:18

标签: python dictionary

我有这个计算欧几里德相似度的程序。

from math import sqrt

def leeValoraciones(nomFichero):
    lineas = [(l.strip()).split("\t") for l in (open(nomFichero).readlines())]
    diccio = {}
    for l in lineas:    
        diccio[int(l[0])] = {}
    for l in lineas:
        diccio[int(l[0])][int(l[1])] = (float(l[2]),float(l[3]))
    return diccio

def euclideanDist(dic1, dic2):
    # Compute the sum of squares of the elements common
    # to both dictionaries
    sum2 = sum([pow(dic1[elem]-dic2[elem], 2)
                for elem in dic1 if elem in dic2])
    return sqrt(sum2)

def euclideanSimilarity(dic1, dic2):
    return 1/(1+euclideanDist(dic1, dic2))

diccio = leeValoraciones("u.data")
diccio2 = leeValoraciones("u.data")


euclideanSimilarity(diccio,diccio2)

当我运行程序时,它返回以下错误:

for elem in dic1 if elem in dic2])
TypeError: unsupported operand type(s) for -: 'dict' and 'dict'

有人可以帮助我吗? 提前谢谢。

2 个答案:

答案 0 :(得分:0)

您的外部词典包含嵌套词典。你试图减去那些:

for l in lineas:    
    diccio[int(l[0])] = {}
for l in lineas:
    diccio[int(l[0])][int(l[1])] = (float(l[2]),float(l[3]))

因此,您的字典具有结构{integer: {integer: (float, float)}},但您只能遍历外部字典。并不是说你可以减去最里面的元组。

您可能应该使用两个整数作为坐标,为您提供一个指向浮点元组的外部字典,格式为{(integer, integer): (float, float)}

你可以通过文件上的一个循环实现这一点,实际上不需要循环两次(或者首先将所有行读入内存)。使用csv模块有助于将行读入行:

import csv

def leeValoraciones(nomFichero):
    with open(nomFichero, 'rb') as csvfile:
        reader = csv.reader(csvfile, delimiter='\t')
        results = {}
        for row in reader:
            key = tuple(int(c) for c in row[:2])
            value = tuple(float(c) for c in row[2:4])
            results[key] = value
    return results

但是,我不确定你要用这里计算欧几里德距离;你传入两个完全相同的文件构建的字典。这两个文件的所有点之间的欧几里德距离恰好为0。

如上所述,您不能将(float, float)元组用作Euclidian空间中的单个点,您有一个系列点。你需要决定你计算距离的点数。

答案 1 :(得分:0)

首先,这是整个程序,如果没有,请发布整个程序。其次,我相信,从你的错误来看,for elem in dic1 if elem in dic2])应该是

for elem in dic1:
    if elem in dic2:
       Do things

第三个也是最后一个,你的错误就是说你试图减去字典,这没有意义。尝试改为

for elem in dic1:
    if elem in dic2:
       dic1[elem]-dict2[elem]

现在,这个答案可能完全错误,但这就是你发布的内容。请发布整个代码,以及u.data

的内容