2014-10-29 48 views
1

我正在使用使用字典的数据集。数据集不能保证符合其每个部分。有时我收到重要错误或与密钥没有任何关联。我无法弄清楚的是如何处理这个问题。因为我经常遇到这个问题。它使我防守地在每一行或每一步上进行编程。所以我想知道的是如何处理结构和逻辑?令我困惑的是。我是否应该使用字典默认键,如果没有值,则默认为假真值,这将跟随真值表达式。这看起来非常笨重,并且在每个实例中都要做很多工作?这里是使用我的数据结构的情况的例子。Python - 如何在防御性和逻辑上用不兼容的数据集进行编程 - 字典

坏项目 ​​- 无结束时间关键,没有名称

job = {'name':'', 'starttime':, 'definition': [long list of stuff]} 

好项目

job = {'name':'name', 'starttime':5.5, 'endtime':6.5 'definition': 
[long list of stuff]} 
for job in batch: 
      job_name = job.get('name', 'Error: No job name found!') 
      start_time = float(job.get('starttime', 0.0)) 
      if start_time: 
       current_runtime = time.time() - start_time 
      end_time = float(job.get('endtime', 0.0)) 
      job_definition = job.get('definition', 'Error: No definition found!') 
      parse_jobdef = parse_job_definition(job_definition) 
      job_depends = parse_jobdef.get('depends', 'Error: No depends found!') 

      average_runtime = get_average_runtime(job_name) 

所以,如果没有名字......然后我的程序崩溃。如果不是开始时间,它可能会崩溃。如果这是在迭代中,并不意味着整个程序会崩溃,但只是项目是坏的。我想继续下一次迭代。

这是更具概括性的问题,更少的具体情况。

在处理迭代内的数据结构时如何处理不良数据?所以丢失的键和空值。我是否应该在整个代码中处理捕捉或声明。这是处理它的唯一方法吗?

+0

如果你打算用假值做的是打印“错误:没有任何发现”并退出,那么你不妨完全跳过'get',只是做'my_dict [key]'。这会让你的程序崩溃,当然,但从用户的角度来看,任何一种方法都是一样的。他们看到一条错误消息,并停止工作。 – Kevin 2014-10-29 20:30:10

+0

不,那不好。因为只有那个特定的迭代是不好的......批次的其余部分可能是好的,需要继续。 – user3590149 2014-10-29 20:41:09

+0

您可以使用示例清理数据和您看到的脏数据示例更新问题。强调哪些(是)不应该丢失的重要关键。 – 2014-10-29 20:47:36

回答

0

你很可能不得不单独检查每个键的一致性以真正解决问题。您可能能够压缩其中的一些内容,例如检查密钥列表是否存在并且不是空的,或者大于零。但是,根据您需要的详细程度,您可能需要检查特定键的值是否在一个范围内,或者根据一些标准看来是有效的。无论你做什么,用0之类的东西替换一个无效值都需要非常小心。很可能你只是在破坏你的数据,并且说服你的程序的其余部分这个数据集是有效的,而这些数据实际上只是随机默认值。如果您发现不一致,您应该跳过该记录并使用continue继续前进。为防止不必要的庞大,您可以将所有内容都包含在try块中,以防止必须明确检查密钥是否存在。

try: 
    for need_not_empty_key in ["name", "start_time"]: 
     if not job[need_not_empty_key]: 
      #A required key is empty 
      #Log the problem 
      continue 

    #Verify something about a specific key 
    job_name = job["name"] 
    if len(job_name) < 4: 
     #Name is less than 4, it must be bad 
     #Log the problem! 
     continue 

    #Rest of work here 
    #Save results of this iteration here 
except KeyError: 
    #We must not have a needed key 
    #Do some logging here instead of passing! 
    pass 
+0

这是我要求的。这个概念上解决了这个问题。无庸置疑,这是一个很好的解决方案,工作解决方案和糟糕的解决方案。我正在寻找良好的做法,原则和思想。谢谢。如果需要的话,任何进一步的评论会很棒 – user3590149 2014-10-29 21:01:17

+0

我添加了一个示例,它允许您验证密钥是否存在以及它们是否为空或0,并且体积最小。我也认为这是合理的pythonic。 – ErlVolton 2014-10-29 21:05:07

0

为什么不能做这样的事情:

def has_keys(_dict, keys): 
    for _key in keys: 
     if not _dict.has_key(_key): 
      logging.debug('{0} has no key {1}'.format(_dict, _key)) 
      return False 

    return True 



def your_function_where_you_do_stuff(): 
    ... 
    _keys = ['name', 'starttime', 'endtime', 'definition', 'depends'] 
    for job in batch: 
     if not has_keys(job, _keys): 
      continue 

     job_name = job[name] 
     ... 
0

我会怎么做:

键=( '名称', '开始时间', '结束时间', '定义')

作业在批次: 临时= dict.fromkeys(键) temp.update(作业)

这样你就可以随时获得所有你需要的钥匙,缺少的钥匙会有一个None值。

http://www.tutorialspoint.com/python/dictionary_fromkeys.htm

(对不起,我我的手机上)

+0

我通常更喜欢确保我需要的东西像上面那样做,而不是测试它是否存在。它通常更快,更容易处理。 – 2014-10-29 21:37:04