【问题标题】:if __ and __ in ___ then如果 __ 和 __ 在 ___ 那么
【发布时间】:2011-04-11 17:21:11
【问题描述】:

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

我需要查看能力标识符的有限列表 (400)(例如 124、129 等 - 正常整数)

然后我有一本字典,记录了每个用户的能力。 Key 是用户名,每个 key 的 value 是一个整数列表(即用户拥有哪些能力)

例如

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 __ 和 __ then 操作时是否存在强制完全匹配的方法。

或者有没有人对如何实现这一点提出改进建议...

提前感谢您的任何指点。干杯

【问题讨论】:

  • common_competencies = str("")??? Python 不是 Java。 some_var = '' 已经足够好了
  • @RestRisiko:你是怎么用 Java 写的?
  • 不知道 - 但在这里使用 str(..) 没有意义
  • @khachik 我不是 Java 粉丝,但 Java 确实有字符串文字。 :)
  • @Chris Taylor:你在哪里见过像这样使用and 的代码?您能提供报价或链接或参考吗?这是非常非常错误的事情。你在哪里看到的?

标签: python list if-statement dictionary


【解决方案1】:

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

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

您的版本执行其他操作。它像这样绑定:if (comp1) and (comp2 in d1[person])。换句话说,它将comp1 解释为真值,然后对您的列表包含检查执行布尔值and。这是有效的代码,但它并不能满足您的要求。

【讨论】:

    【解决方案2】:

    这应该会运行得更快一些,因为它消除了额外的迭代层。希望对您有所帮助。

    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 中处理该文件。

    【讨论】:

    • 很好地使用lambda 进行嵌套字典实例化。
    【解决方案3】:

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

    【讨论】:

    • 抱歉,当我在堆栈溢出时输入此缩进时出现错误 - 第二个循环缩进以嵌套在第一个循环中。
    猜你喜欢
    • 1970-01-01
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-22
    相关资源
    最近更新 更多