【问题标题】:Optimize code with dictionary comprehension使用字典理解优化代码
【发布时间】:2019-06-07 19:02:04
【问题描述】:

我正在尝试优化我的代码,但我发现了理解。但是我正在为我的代码以及如何应用字典理解而苦苦挣扎。 原始代码如下。

如何以适当的 Python 方式优化此代码?

all_users = []
for x in range(len(result)):
    user = {}
    user["fieldy"] = str(result[x][1].get("valueforfield1", None))[3:-2]
    user["fieldx"] = str(result[x][1].get("valueforfield2", None))[3:-2]
    user["fieldc"] = str(result[x][1].get("valueforfield3", None))[3:-2]
    user["fieldv"] = str(result[x][1].get("valueforfield4", None))[3:-2]
    user["fieldb"] = str(result[x][1].get("valueforfield5", None))[3:-2]
    all_users.append(user)

结果的示例值

result = [('CN=Xxx X,OU=X,OU=X,DC=X,DC=X', {'valueforfield1': [b'Va'], 'valueforfield2': [b'val'], 'valueforfield3': [b'+123'], 'valueforfield4': [b'65@test.com'], 'valueforfield5': [b'examplevalue']}),('CN=Yyy Y,OU=Y,OU=Y,DC=Y,DC=Y', {'valueforfield1': [b'Ycx'], 'valueforfield2': [b'Dy'], 'valueforfield3': [b'+321'], 'valueforfield4': [b'64@test.com'], 'valueforfield5': [b'examplevaluey']})]

代码执行后,user 字典在 for 循环的第一次迭代后具有以下内容

{"fieldy": "Va", "fieldx": "val", "fieldc": "+123", "fieldv": "65@test.com", "fieldb": "examplevalue"}

我还应该编写一个函数来替换user["field1"] = str(result[x][1].get("valueforfield1", None))[3:-2] 代码吗?值得并推荐吗? 谢谢!

【问题讨论】:

  • result 是什么?
  • 你无法真正从速度上优化它,只能让代码更简洁
  • 发布您的result
  • 抱歉,已更新。
  • @jv95,好的,你怎么定义fieldy对应valueforfield1?依据什么标准?

标签: python dictionary dictionary-comprehension


【解决方案1】:

采用精心设计的方法:

result = [('CN=Xxx X,OU=X,OU=X,DC=X,DC=X',
           {'valueforfield1': [b'Va'], 'valueforfield2': [b'val'], 'valueforfield3': [b'+123'],
            'valueforfield3': [b'65@test.com'], 'valueforfield5': [b'examplevalue']}),
          ('CN=Yyy Y,OU=Y,OU=Y,DC=Y,DC=Y',
           {'valueforfield1': [b'Ycx'], 'valueforfield2': [b'Dy'],
            'valueforfield3': [b'+321'], 'valueforfield3': [b'64@test.com'],
            'valueforfield5': [b'examplevaluey']})]

def compose_user_details(data):
    keys_map = {"fieldy": "valueforfield1", "fieldx": "valueforfield2",
                "fieldc": "valueforfield3", "fieldv": "valueforfield4",
                "fieldb": "valueforfield5", "fieldn": "valueforfield6",
                }
    user_details = []

    for i in range(len(result)):
        dataset = result[i][1]  # getting the needed `data source` at once
        user_details.append({k: str(dataset.get(v, None))[3:-2]
                             for k,v in keys_map.items()})
    return user_details

print(compose_user_details(result))

输出:

[{'fieldy': 'Va', 'fieldx': 'val', 'fieldc': '65@test.com', 'fieldv': '', 'fieldb': 'examplevalue', 'fieldn': ''}, {'fieldy': 'Ycx', 'fieldx': 'Dy', 'fieldc': '64@test.com', 'fieldv': '', 'fieldb': 'examplevaluey', 'fieldn': ''}]

【讨论】:

  • @jv95,不客气。如果不需要,您可以从 keys_map 中删除 "fieldn": "valueforfield6" 项目。
【解决方案2】:

仅使用字典推导来处理重复代码:

all_users = []
for x in range(len(result)):
    user = {f"field{i}": str(result[x][1].get(f"valueforfield{i}", None))[3:-2] for i in range(1, 7)}
    all_users.append(user)

同时使用列表推导和字典推导在一行中完成所有操作:

all_users = [{
        f"field{i}": str(result[x][1].get(f"valueforfield{i}", None))[3:-2] 
        for i in range(1, 7)
    } for x in range(len(result))]

您提供的示例中的困难在于键的名称 - 但由于这些是常规的,我使用格式字符串来插入键期望的整数(即,f"field{i}" 解析为 "field1"i = 1"field2"i = 2,等等)。


一般来说,推导并没有真正优化速度——它们更多的是为了避免代码重用。

【讨论】:

  • 那是非常好看的解决方案。但如果名字不那么好听,你会怎么做?我有另一部分代码有同样的问题,但名称就像.. fieldexample 应该从 valueforexamplefield 中获取值等等......这里我不能在 i = 1 时使用你的“field1”,当 i = 2 时使用“field2”如何你会解决吗?我没有发布代码,因为我认为我可以将解决方案用于我拥有的两个循环
  • @jv95,你为什么不发布一个有代表性的、可测试的输入结构?
  • @jv95 如果你想对该数据使用理解,你需要建立一个系统来识别什么键应该对应什么值。例如,您可以使用硬编码的dict 索引作为键,并将其放入格式字符串中 - 例如my_dict={1:'y', 2:'x', ...},然后是 f"field{my_dict[i]}"。或者想出一些其他可行的解决方案来解决这个问题
  • 这是不可能的,因为每次运行代码时结果都会有所不同。基本上,这背后的整个想法是在 all_users 中创建字典,并用来自 result 的值填充这些字典。 result 的长度和值每次都会不同。结果中唯一的静态是键名 valueforfield1
猜你喜欢
  • 1970-01-01
  • 2011-06-21
  • 2019-09-19
  • 1970-01-01
  • 2021-12-02
  • 2022-11-23
  • 1970-01-01
  • 1970-01-01
  • 2014-06-09
相关资源
最近更新 更多