如果在___中__和__那么

时间:2011-04-11 17:21:12

标签: python list if-statement dictionary

我正在尝试创建一个循环遍历列表的脚本。

我需要查看能力标识符的有限列表(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

这不起作用,只返回每个能力总体发生的次数。我认为问题在于“如果comp和comp2在d1 [person]:”行中。

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

或者有人提出改进建议如何实现这一目标......

提前感谢任何指针。干杯

3 个答案:

答案 0 :(得分:8)

你误解了and的工作原理。要测试列表中是否有两个值,请使用:

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

你的版本做了别的事情。它绑定如下:if (comp1) and (comp2 in d1[person])。换句话说,它将comp1解释为真值,然后使用列表包含检查进行布尔and。这是有效的代码,但它不能满足您的需求。

答案 1 :(得分: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中使用它。

答案 2 :(得分:0)

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