根据键名和值组合动态排序数据

时间:2015-01-06 04:36:52

标签: python algorithm sorting key key-value

所以,我首先会说我在编程方面很糟糕。但是,我已经接触到了足够的好的程序员,我觉得必须有一个更优雅的解决方案来解决我正在尝试做的事情 - 我希望也许有人会知道一个。

我正在尝试找到一种排序数据的好方法(我几乎无法控制)。数据作为一组dicts传递 - 所有相同的定义 - 我将根据以下标准进行排序:

  • 任何键名都可能拥有特定属性,例如以特殊字符开头(在此示例中为“o”)

  • 单个字典中的一个或多个键可能拥有此属性

  • 如果该属性存在,请将这些dicts组合在一起拥有该属性的键的所有值相同

  • 显示和返回数据的顺序不重要

例如,给定以dict格式的以下输入数据:

+--------+---------+-------+--------------+
| 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

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

1 个答案:

答案 0 :(得分: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))

但是,会匹配您示例中的保持顺序的特征(我相信,您提供的代码也不会与之相符)。