2011-04-11 63 views
1

我想创建一个脚本,通过列表循环。如果__和__在___然后

我需要通过能力标识符的有限名单(400)(例如124,129等 - 正常整数)看起来则有

我说什么记录能力每个用户都拥有一本字典。关键是用户名和每个键的值是一个整数列表(即其能力的用户有)

例如

User x - [124, 198, 2244 ...] 
User Y - [129, 254, 198, 2244 ...] 

我期待编译矩阵突出多久每种能力与所有其他能力一起发生 - 邻接矩阵。

例如在上述示例中,胜任特征198在两次出现时与胜任特征2244发生。而能力254和124从未一起出现。

我目前使用此代码:

fe = []  
count = 0 
competency_matches = 0 
for comp in competencies_list: 
    common_competencies = str("") 
for comp2 in competencies_list: 
    matches = int(0) 
    for person in listx: 
     if comp and comp2 in d1[person]: 
      matches = matches + 1 
     else: 
      matches = matches 
    common_competencies = str(common_competencies) + str(matches) + "," 
fe.append(common_competencies) 
print fe 
print count 
count = count + 1 

这不工作,只是返回了多少次每种能力已全面发生了。我认为问题在于“如果在comp1和comp2中,在d1 [person]:”行中。

例如,如果一个人具有以下能力[123,1299,1236],并且我搜索了能力123,则该问题将返回两次,因为这出现在123和1236个条目中。在使用if __和__ then操作时,是否存在强制进行精确匹配的方法。

或者有没有人有一个完善的建议如何实现这一目标?

预先感谢任何指针。欢呼声

+0

common_competencies = str(“”)??? Python不是Java。some_var =''足够好 – 2011-04-11 17:26:33

+0

@RestRisiko:你如何在Java中编写它? – khachik 2011-04-11 17:29:23

+0

不知道 - 但在这里使用str(..)没有意义 – 2011-04-11 17:30:13

回答

8

你误解了and的工作原理。为了测试两个值是否在列表中,使用方法:

if comp1 in d1[person] and comp2 in d1[person]: 
    ... 

你的版本做别的事情。它像这样绑定:if (comp1) and (comp2 in d1[person])。换句话说,它将comp1解释为真值,然后使用列表包含检查来执行布尔值and。这是有效的代码,但它不会做你想要的。

+0

谢谢你 - 现在更有意义 – 2011-04-11 17:37:54

0

此处的缩进意味着您的两个循环不是嵌套的。您首先通过competencies_list进行迭代并将common_competencies设置为空字符串400次,然后再次遍历competencies_list并执行phooji解释的操作。我很确定那不是你想要做的。

+0

道歉,当我在堆栈溢出中输入这个缩进时,缩进出现了错误 - 第二个循环缩进成为嵌套在第一个循环中。 – 2011-04-11 17:47:45

3

这应该运行得更快一些,因为它消除了一个额外的迭代层。希望能帮助到你。

from collections import defaultdict 
from itertools import combinations 

def get_competencies(): 
    return { 
     "User X": [124, 198, 2244], 
     "User Y": [129, 254, 198, 2244] 
    } 

def get_adjacency_pairs(c): 
    pairs = defaultdict(lambda: defaultdict(int)) 
    for items in c.itervalues(): 
     items = set(items) # remove duplicates 
     for a,b in combinations(items, 2): 
      pairs[a][b] += 1 
      pairs[b][a] += 1 
    return pairs 

def make_row(lst, fmt): 
    return ''.join(fmt(i) for i in lst) 

def make_table(p, fmt="{0:>8}".format, nothing=''): 
    labels = list(p.iterkeys()) 
    labels.sort() 

    return [ 
     make_row([""] + labels, fmt) 
    ] + [ 
     make_row([a] + [p[a][b] if b in p[a] else nothing for b in labels], fmt) 
     for a in labels 
    ] 

def main(): 
    c = get_competencies() 
    p = get_adjacency_pairs(c) 
    print('\n'.join(make_table(p))) 

if __name__=="__main__": 
    main() 

结果

   124  129  198  254 2244 
    124      1    1 
    129      1  1  1 
    198  1  1    1  2 
    254    1  1    1 
    2244  1  1  2  1   

...显然是一个400列的表格是有点多打印到屏幕上;我建议使用csv.writer()将它保存到一个文件中,然后您可以在Excel或OpenOffice中使用它。

+0

很好地使用'lambda'来嵌套字典实例化。 – phooji 2011-04-11 18:50:32