【问题标题】:Sorting data dynamically based upon key names and value combos根据键名和值组合动态排序数据
【发布时间】:2015-01-06 04:36:51
【问题描述】:

所以,我首先要说我在编程方面很糟糕。然而,我接触过足够多的优秀程序员,我觉得必须有一个更优雅的解决方案来解决我正在尝试做的事情——我希望这里有人会知道。

我正在尝试找到一种对数据进行排序的好方法(我几乎无法控制)。数据以字典数组的形式传递——所有的定义都相同——我将根据以下标准进行排序:

  • 任何键名都可能具有特定属性,例如以特殊字符开头(在本例中为“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

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

【问题讨论】:

  • 从你所说的,听起来你的字典代表一个表格结构(每个字典都是表格中的一行)。如果是这种情况,您应该查看pandas 库,它提供了许多用于处理表格数据的有用工具。

标签: python algorithm sorting key key-value


【解决方案1】:

我想了解是否可以假设所有 prop 字段相同的记录已经彼此相邻排序——我将假设这一点,因为否则将需要排序,我无法猜测在您要使用的排序标准。所以...:

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

但是,这将符合您的示例的顺序保留特征(我相信您的代码也不符合您展示的代码)。

【讨论】:

  • 这正是我希望从这个问题中学到的,非常感谢您抽出宝贵的时间。您的假设是正确的,我不在乎订单,因为它根本不重要。我已经编辑了原始问题以确保更清楚。
猜你喜欢
  • 2019-06-09
  • 1970-01-01
  • 2013-05-14
  • 2017-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-24
  • 1970-01-01
相关资源
最近更新 更多