如果__和__在___中,则
我正在尝试创建一个脚本,用来遍历一个列表。
我需要查看一个有限的列表(有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
但是这个代码不管用,只是返回每个能力总共出现了多少次。我觉得问题出在“if comp and comp2 in d1[person]:”这一行。
问题在于,比如说一个人拥有的能力是[123, 1299, 1236],如果我搜索能力123,这个能力会被返回两次,因为它出现在123和1236这两个条目中。有没有办法强制进行精确匹配,当使用“if __ and __ then”这种操作时。
或者有没有人有更好的建议来实现这个目标……
提前感谢任何指点。谢谢!
3 个回答
你这里的缩进表示你的两个循环并没有嵌套在一起。你首先会遍历一次 competencies_list
,然后把 common_competencies
设置为空字符串,这个过程会重复400次。接着你又会遍历一次 competencies_list
,然后做phooji解释的事情。我敢肯定,这不是你想要的结果。
这样做应该会快很多,因为它去掉了多余的一层循环。希望这对你有帮助。
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中处理它。
你误解了and
的用法。要检查两个值是否在一个列表中,可以使用:
if comp1 in d1[person] and comp2 in d1[person]:
...
你写的版本做的事情不一样。它的逻辑是这样的:if (comp1) and (comp2 in d1[person])
。换句话说,它把comp1
当作一个真假值来处理,然后再和你检查列表包含的部分做一个布尔and
运算。这段代码是有效的,但它并没有实现你想要的效果。