在列表列表中找到的关联字典(性能问题)

时间:2015-02-11 17:30:04

标签: python dictionary

对象:生成一个dict,显示base[2:]中哪些唯一值(在列表uniques中捕获)与 base[1]值(即5001,5002等)。 下面的代码有效,但对于数据量I来说太慢了 需要处理,所以我正在寻找一种更快的方法来实现这一目标。

base = [['a', 5001, 1, 4, 8],
        ['b', 5002, 2, 5],
        ['c', 5002, 2, 5],
        ['d', 5003, 2, 6, 7],
        ['e', 5004, 3, 6, 9]]

uniques = [1,2,3,4,5,6,7,8,9]

uniques_dict = {}

for item in uniques:
    uniques_dict[item] = list(set([records[1] for records in base if item in records[2:]]))

print(uniques_dict)

Output:
{   1: [5001], 2: [5002, 5003], 3: [5004], 
    4: [5001], 5: [5002], 6: [5003, 5004], 
    7: [5003], 8: [5001], 9: [5004] }

1 个答案:

答案 0 :(得分:1)

不是一遍又一遍地遍历所有records,而是反转循环。将uniques设置为设置以进行快速成员资格测试,并将records循环一次。

更好的是,该集可以通过字典键来处理:

uniques_dict = {u: [] for u in uniques}

for record in base:
    key, values = record[1], record[2:]
    for unique in uniques_dict.keys() & values:  # the intersection
        uniques_dict[unique].append(key)

在Python 3中,dict.keys()是一个dictionary view object,就像一个集合。您可以使用&和运算符创建与该集合的交集。如果您使用的是Python 2,请将uniques_dict.keys()替换为uniques_dict.viewkeys(),以获得完全相同的行为。

设置交叉点快速有效;你仍然需要将record[2:]中的每个元素与仍然存在的密钥集匹配,但它是O(N)循环而不是O(NK)循环,因为每个密钥测试是独立于K =的O(1)操作len(unique_keys)

演示:

>>> base = [['a', 5001, 1, 4, 8],
...         ['b', 5002, 2, 5],
...         ['c', 5002, 2, 5],
...         ['d', 5003, 2, 6, 7],
...         ['e', 5004, 3, 6, 9]]
>>> uniques = [1,2,3,4,5,6,7,8,9]
>>> uniques_dict = {u: [] for u in uniques}
>>> for record in base:
...     key, values = record[1], record[2:]
...     for unique in uniques_dict.keys() & values:  # the intersection
...         uniques_dict[unique].append(key)
... 
>>> uniques_dict
{1: [5001], 2: [5002, 5002, 5003], 3: [5004], 4: [5001], 5: [5002, 5002], 6: [5003, 5004], 7: [5003], 8: [5001], 9: [5004]}

如果uniquesbase[*][2:]中所有可能值的严格超集,那么您甚至不必预先计算这些值。只需在开始时创建字典键,并在每个set()列表上使用record[2:]来仅处理唯一值。还应设置uniques_dict值以消除添加的重复键:

uniques_dict = {}

for record in base:
    key, values = record[1], record[2:]
    for unique in set(values):
        uniques_dict.setdefault(unique, set()).add(key)

现在list(uniques_dict)是您在处理base时构建的唯一身份列表:

>>> uniques_dict = {}
>>> for record in base:
...     key, values = record[1], record[2:]
...     for unique in set(values):
...         uniques_dict.setdefault(unique, set()).append(key)
... 
>>> uniques_dict
{1: {5001}, 2: {5002, 5003}, 3: {5004}, 4: {5001}, 5: {5002}, 6: {5003, 5004}, 7: {5003}, 8: {5001}, 9: {5004}}
>>> list(uniques_dict)
[1, 2, 3, 4, 5, 6, 7, 8, 9]