2015-01-06 65 views
0

所以,我首先说我在编程方面很糟糕。不过,我已经接触到了足够的程序员,我觉得我必须有一个更优雅的解决方案来实现我想做的事情 - 我希望也许这里有人会知道其中的一个。基于密钥名称和值组合动态地对数据进行排序

我想找到一个很好的方法来排序数据(我几乎没有控制权)。所有相同定义 - - 的数据被作为http://stardict.sourceforge.net/Dictionaries.php下载的阵列过去了,我将被分选基于以下标准:

  • 任意键名称可以具有特定的属性,如开始以特殊字符(在这个例子中,一个“O”)

    单个字典内
  • 一个或多个密钥可具有该属性

  • 如果该属性出现,组这些类型的字典在一起,其中密钥的所有值具有该物业相同

  • 该数据被呈现和返回的顺序并不显著

例如,给定在字典格式下面的输入数据:

+--------+---------+-------+--------------+ 
| o_last | first | o_zip | likes  | 
+--------+---------+-------+--------------+ 
| Smith | Bob  | 12345 | Apples  | 
| Smith | Alice | 12345 | Peaches  | 
| Smith | Marvin | 54321 | Strawberries | 
| Jones | Steve | 98765 | Potatoes  | 
| Jones | Harold | 98765 | Beets  | 
| White | Carol | 00001 | Fish   | 
+--------+---------+-------+--------------+ 

以下基团将被输出:

+--------+---------+-------+--------------+ 
| Smith | Bob  | 12345 | Apples  | 
| Smith | Alice | 12345 | Peaches  | 
+--------+---------+-------+--------------+ 

+--------+---------+-------+--------------+ 
| Smith | Marvin | 54321 | Strawberries | 
+--------+---------+-------+--------------+ 

+--------+---------+-------+--------------+ 
| Jones | Steve | 98765 | Potatoes  | 
| Jones | Harold | 98765 | Beets  | 
+--------+---------+-------+--------------+ 

+--------+---------+-------+--------------+ 
| White | Carol | 00001 | Fish   | 
+--------+---------+-------+--------------+ 

下面是我现在已经实现的功能,到目前为止它似乎工作正常。但是,正如我上面提到的,我不得不相信,我不知道可以使用更优雅的库或设计模式。

def sort_data(input_d): 

    fields = [] 
    has_prop = False 
    prop_fields = [] 
    prop_dict = {} 
    out_list = [] 

    # create a list of keys that have the property 
    [fields.append(x) for x in input_d[0].keys()] 
    for field in fields: 
     if re.match("^o[a-np-zA-NP-Z]*_", field): 
      has_prop = True 
      prop_fields.append(field) 

    # if keys are found: 
    if has_prop: 
     for d in input_d: 
      prop_vals = "" 
      for f in prop_fields: 
       prop_vals += d[f] 

      # create an md5 hash of unique values for keys with property 
      # and use it to group dicts with the same value combinations 
      prop_vals_hash = hashlib.md5(prop_vals).hexdigest() 
      if prop_vals_hash in prop_dict: 
       prop_dict[prop_vals_hash].append(d) 
      else: 
       prop_dict[prop_vals_hash] = [d] 

     # return data as an array of arrays, with each index 
     # in that array a grouping of dicts with unique value combinations 
     for k in prop_dict.keys(): 
      out_list.append(prop_dict[k]) 

    # default for input data that does not have keys possessing 
    # our property of interest 
    else: 
     for d in input_d: 
      output_list.append([d]) 

    return output_list 

我很想听听任何人愿意提供的任何和所有回复,建议,批评或反馈。谢谢阅读!

+0

从你说的话来看,这听起来像你的字典代表一个表格结构(每个字典是表中的一行)。如果是这样,你应该看看[pandas](http://pandas.pydata.org/)库,它提供了许多有用的工具来处理表格数据。 – BrenBarn

回答

0

我想了解是否所有道具字段完全相同的记录可以假设为已经排序成彼此相邻 - 我将假设,否则将需要排序,而且我不能猜测你想要使用的排序标准。所以...:

output_list = [] 
prop_fields = [k for k in input_d[0] if k.startswith('o')] 

# if keys are found: 
if prop_fields: 
    for k, g in itertools.group_by(input_d, key=operator.itemgetter(*prop_fields)): 
     output_list.append(list(g)) 
else: 
    output_list = [[d] for d in input_d] 
return output_list 

如果“秩序是好的,必须保持”条件不适用,那么你就必须添加的if prop_fields:

input_d.sort(key=operator.itemgetter(*prop_fields)) 

后正确的,但,那与您的示例中的顺序保留特征相匹配(我相信,您的代码在呈现时也是如此)。

+0

这正是我希望从这个问题中学到的东西,非常感谢您抽出时间。你的假设是现货,我不关心订单,因为它并不重要。我编辑了原始问题以确保更清楚。 – ajn