【问题标题】:Proper way for Indexing sorted data in Python在 Python 中索引排序数据的正确方法
【发布时间】:2017-10-29 16:36:57
【问题描述】:

在 Python 中有一个包含字典元素的排序列表,长度为 1000,如下所示

[
 {'date': '2017-05-20', 'category': 'create', 'data': 23}, 
 {'date':'2017-05-21', 'category': 'use', 'data': 1}, 
 {'date': '2017-05-23', 'category': 'create', 'data': 4},
]

列表的每个元素都包含带有字段的字典

  1. 日期
  2. 类别
  3. 数据

列表按字典元素的日期排序。


问题是基于列表的函数有两种类型

  • 日期按列表排序(这就是数据按日期排序的原因)
  • 数据类别

因此,我必须多次遍历完整列表才能对单个类别进行操作。


我想出的一个解决方案是维护一个字典,其中键作为类别,值作为排序列表中的索引。

index = {'create': [0, 2], 'use': [1]}

我想知道实现此功能的最佳或 Python 方式是什么?或者如果有任何这样的数据结构。

【问题讨论】:

  • 如果大小足够小,索引列表是个不错的方法。如果列表的大小或搜索的复杂性增加,您可能有兴趣将排序列表转换为 SQLite 表并在其上使用 SQL 查询。
  • 感谢 Serge,然后我会采用上述方法,直到找到其他更好的方法。

标签: python list sorting dictionary indexing


【解决方案1】:

你的想法不错。您甚至可以定义一个将类别作为输入的生成器函数,如下所示

def list_by_category(category, original_list):
  for entry in original_list:
    if entry['category'] == category:
      yield entry

用法:

# Do something with 'create':
for entry in list_by_category('create'):
  print entry
  # Do things here..

.

这样可以避免为每个类别维护另一个列表的内存开销。

【讨论】:

  • 但是@gipsy,我不想遍历每个类别的完整列表。这首先是问题所在。
  • 是的,那么您的索引想法更有意义。
  • 我想知道这个问题有没有pythonic解决方案。
  • 您可以使用 defaultdict 使索引更清晰。我添加了一个新的答案看看
【解决方案2】:

为类别createuse 创建两个额外的字典,其键由列表中的记录索引表示。

例如:

create_dict = {0: {'date': '2017-05-20', 'category': 'create', 'data': 23},
               2: {'date': '2017-05-23', 'category': 'create', 'data': 4}}

use_dict = {1: {'date':'2017-05-21', 'category': 'use', 'data': 1}}

但是,假设是原始列表中的索引没有改变。

如果原始列表中的日期字段也是唯一的,您可以创建一个类似的字典,其中键是日期。使用字典,您可以快速(O(1))通过键访问所有元素。如果您处理非常大的字典,缺点是内存使用量。

【讨论】:

  • 当我必须对日期进行操作时,我必须进行大量开销计算以对日期进行排序。不,日期在原始列表中不是唯一的。
  • @infiQuanta,然后将索引用作附加字典中的键(如果它们不更改)。
【解决方案3】:
from collections import defaultdict
original_list = [
 {'date': '2017-05-20', 'category': 'create', 'data': 23}, 
 {'date':'2017-05-21', 'category': 'use', 'data': 1}, 
 {'date': '2017-05-23', 'category': 'create', 'data': 4},
]

# indexing 

category_index = defaultdict(list)
for idx, entry in enumerate(original_list):
  category_index[entry['category']].append(idx)


# using the index:

# Working with 'create'

for idx in category_index['create']:
  print original_list[idx]
  # Do things with entry

# Working with 'use'

for idx in category_index['use']:
  print original_list[idx]
  # Do things with entry

【讨论】:

  • 通过这种方式,我们再次复制了完整的列表。我认为这是浪费内存。
  • 如果空间是一个问题,只需附加索引而不是条目本身。
  • 更新了我的答案,只将列表索引存储在 category_index 中
  • 是的,这就是我正在做的,并在问题声明中发布了这个解决方案。但是,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多