【问题标题】:How to increment value in dictionary using python如何使用python增加字典中的值
【发布时间】:2020-06-12 10:48:10
【问题描述】:

我在文本文件中有这些行:

2018-11-06 16:52:01.901| on thread[140447603222272 c0s0]| IP[192.168.0.244:5000]| master| 192.168.0.244| omer| (stmt : 0) | admin|  Success
2018-11-06 16:52:15.160| on thread[140447603222272 c0s1]| IP[192.168.0.244:5001]| master| 192.168.0.244| userAdmin| (stmt : 1) | admin|  Success
2018-11-06 16:52:27.351| on thread[140447603222272 c0s3]| IP[192.168.0.244:5000]| master| 192.168.0.244| userAdmin| (stmt : 3) | admin|  Success
2018-11-06 16:52:28.159| on thread[140447603222272 c0s5]| IP[192.168.0.244:5000]| master| 192.168.0.244| userAdmin| (stmt : 5) | admin|  Success
2018-11-06 16:52:30.485| on thread[140447603222272 c0s7]| IP[192.168.0.244:5000]| master| 192.168.0.244| userAdmin| (stmt : 7) | admin|  Success
2018-11-06 16:52:54.217| on thread[140447603222272 c0s11]| IP[192.168.0.244:5000]| master| 192.168.0.244| Gilc| (stmt : 11) | admin|  Success
2018-11-06 16:53:04.600| on thread[140447603222272 c10s12]| IP[192.168.0.244:5000]| master| 192.168.0.244| userAdmin| (stmt : 12) | admin|  Success
2018-11-06 16:53:05.617| on thread[140447603222272 c10s13]| IP[192.168.0.244:5000]| master| 192.168.0.244| userAdmin| (stmt : 13) | admin|  Success
2018-11-06 16:53:18.958| on thread[140447603222272 c10s14]| IP[192.168.0.244:5000]| master| 192.168.0.244| userAdmin| (stmt : 14) | admin|  Success
2018-11-06 16:53:26.25| on thread[140447603222272 c10s15]| IP[192.168.0.244:5000]| master| 192.168.0.244| Guy| (stmt : 15) | admin|  Success
2018-11-06 16:53:36.816| on thread[140447603222272 c10s17]| IP[192.168.0.244:5005]| master| 192.168.0.244| userAdmin| (stmt : 17) | admin|  Success
2018-11-06 16:53:41.116| on thread[140447603222272 c13s18]| IP[192.168.0.244:5000]| master| 192.168.0.244| userAdmin| (stmt : 18) | admin|  Success
2018-11-06 16:53:51.517| on thread[140447603222272 c13s19]| IP[192.168.0.244:5000]| master| 192.168.0.244| userAdmin| (stmt : 19) | admin|  Success
2018-11-06 16:53:55.500| on thread[140447603222272 c13s21]| IP[192.168.0.244:5000]| master| 192.168.0.244| userAdmin| (stmt : 21) | admin|  Success
2018-11-06 16:53:56.333| on thread[140447603222272 c13s23]| IP[192.168.0.244:5000]| master_backup| 192.168.0.244| userAdmin| (stmt : 23) | admin|  Success
2018-11-06 16:54:03.758| on thread[140447603222272 c13s25]| IP[192.168.0.244:5000]| master| 192.168.0.244| userAdmin| (stmt : 25) | admin|  Success
2018-11-06 16:54:07.891| on thread[140447603222272 c13s26]| IP[192.168.0.244:5000]| master| 192.168.0.244| userAdmin| (stmt : 26) | admin|  Success
2018-11-06 16:54:22.66| on thread[140447603222272 c20s27]| IP[192.168.0.244:5000]| master| 192.168.0.244| ben| (stmt : 27) | admin|  Success
2018-11-06 16:54:27.849| on thread[140447603222272 c20s28]| IP[192.168.0.216:5000]| master_tati| 192.168.0.244| userAdmin| (stmt : 28) | admin|  Success
2018-11-06 16:54:36.533| on thread[140447603222272 c22s29]| IP[192.168.0.244:5000]| master| 192.168.0.244| userAdmin| (stmt : 29) | admin|  Success

我想为每个用户计算他得到了多少行,例如我想为用户'userAdmin'获取这个字典 -> dict = {'userAdmin : 16} 因为有 16 行带有'userAdmin'

我已经实现了以下代码:

def parse_log_file(log_file):
    print(len(""))
    my_path = os.path.abspath(os.path.dirname(__file__))
    path = os.path.join(my_path, log_file)
    with open(path, 'r') as f:
        lines = f.readlines()[1:]
        map = {}
        for line in lines:
            elements = line.strip().lstrip().split('|')
            if elements[8].lstrip() == 'Success':
                map[elements[5].lstrip()] = 1
                if map[elements[5].lstrip()] is not None:
                    map[elements[5].lstrip()] += 1
                # map[elements[5]] = elements[8]

        for k, v in map.items():
            print(k, ':', v)

但这是我得到的错误:

omer : 2
userAdmin: 2
Gilc : 2
Guy : 2
ben : 2

我希望 userAdmin 是 16 而不是 2

【问题讨论】:

    标签: python dictionary tuples


    【解决方案1】:

    如果你的 for 循环,你正在覆盖你的字典里面的条目。

    试试这个:

    def parse_log_file(log_file):
        my_path = os.path.abspath(os.path.dirname(__file__))
        path = os.path.join(my_path, log_file)
        with open(path, 'r') as f:
            lines = f.readlines()[1:]
            d = {}
            for line in lines:
                elements = line.strip().lstrip().split('|')
                if elements[8].lstrip() == 'Success':
                    try:
                        d[elements[5].lstrip()] += 1
                    except KeyError:
                        d[elements[5].lstrip()] = 1
    
            for k, v in d.items():
                print(k, ':', v)
    

    我已将您的字典从 map 更改为 d,因为 map 是一个内置函数,您应该避免覆盖它们,因为它们会产生难以追踪的错误。

    以上代码的输出为:

    userAdmin : 16
    Gilc : 1
    Guy : 1
    ben : 1
    

    这里发生的是我们使用EAFP 逻辑尝试对字典内的变量执行+1。如果失败,我们会捕获KeyError,然后在字典中创建一个新条目。

    【讨论】:

    • 在输出中,用户omer在哪里?
    • @simic0de 因为lines = f.readlines()[1:]而被跳过。
    【解决方案2】:

    可以进行的改进:

    • 分配前检查dict中是否存在key,如果key存在,则增加value

    • 减少lstriprstrip 的过度使用,strip 同时做到这两点

    • 建议您将我们的字典名称从map 更改。那是一个python关键字。

    修改后的解决方案:

    def parse_log_file(log_file):
        print(len(""))
        my_path = os.path.abspath(os.path.dirname(__file__))
        path = os.path.join(my_path, log_file)
        with open(path, 'r') as f:
            lines = f.readlines()[1:]
            mapping = {}
            for line in lines:
                elements = line.split('|')
                # strip the lines of surrounding spaces
                elements = [t.strip() for t in elements]
                if elements[8].lstrip() == 'Success':
                    # check if the key already exists in the dict
                    # create key if not exists
                    if not mapping.get(elements[5]):
                        mapping[elements[5]] = 1
                    else:
                        # increment the value if key exists
                        mapping[elements[5]] += 1
    
            for k, v in mapping.items():
                print(k, ':', v)
    

    这会产生:

    userAdmin : 16
    Gilc : 1
    Guy : 1
    ben : 1
    

    【讨论】:

    • 虽然此代码有效,但由于代码每次循环都必须为它的键调用字典两次,因此效率低下。一次是因为 if 语句,一次是写入字典的现有键,或者在字典中创建新键时。一旦键的数量增加,这将无法很好地扩展。使用LBYL 是python 的有效代码,并且在小范围内,有时可能更具可读性。然而,实际上做你想做的事,然后捕获异常总是会更快。
    【解决方案3】:

    对于每个成功行,您将 map[elements[5].lstrip()] = 1 行中的计数改回 1。

    相反,您希望在用户出现的第一行将计数器初始化为 1,而下一次只需将计数器加 1。

    您可以将逻辑更改为以下内容:

    name = elements[5].lstrip()
    if name in d.keys():
        d[name] += 1
    else:
        d[name] = 1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-10
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多