有效地找到满足关系的对象

时间:2015-02-09 04:49:53

标签: python large-data

假设我有一些对象,例如本例(JSON代码):

{
    "people" : {
        "Alice" : {
            "position" : "Manager",
            "company" : "Company1"
        },
        "Bob" : {
            "position" : "CEO",
            "company" : "Company1"
        },
        "Charlie" : {
            "position" : "CEO",
            "company" : "Company2"
        }
    },
    "companies" : [
        { "name" : "Company1" },
        { "name" : "Company2" }
    ]
}

我想编写一个我可以用来传递的函数get_X_of_Y(x, y),例如get_X_of_Y("CEO", companies[0])并让它返回Bob

我怎样才能有效地为大型数据集执行此操作?我有以下功能:

def get_X_of_Y (x, y):
    for person in people:
        if person.position == x and person.company == company.name:
            return person
    else:
        return None

假设我有成千上万的人和数百家公司。有没有更快的方法来做到这一点然后循环每个人?如果有办法让事情变得更快,我可以预先计算对象。

2 个答案:

答案 0 :(得分:1)

正如mu所说 - 使用数据库。

或者你可以做数据库所做的事情 - 保留CEO的索引。所以有一个看起来像的字典:

ceos = { "Company1": "Bob", "Company2": "Charlie" }

并从那里选择。每次人员列表也发生变化时,您都必须更新该dict。

但对于真实场景?...只需使用数据库。


编辑:关于评论“如果我不知道我正在寻找什么位置怎么办” - 再次做数据库做的事情 - 从两个元素/列创建一个索引:

positions_index = {
    ("Company1", "CEO"): "Bob",
    ("Company1", "Manager"): "Alice",
    ("Company2", "CEO"): "Charlie",
}

答案 1 :(得分:1)

让我们说

data = {
    "people" : {
        "Alice" : {
            "position" : "Manager",
            "company" : "Company1"
        },
        "Bob" : {
            "position" : "CEO",
            "company" : "Company1"
        },
        "Charlie" : {
            "position" : "CEO",
            "company" : "Company2"
        }
    },
    "companies" : [
        { "name" : "Company1" },
        { "name" : "Company2" }
    ]
}

然后你可以创建一个人员列表,与你的嵌套字典相比,它基本上是一个扁平的结构:

>>> people = [(key, value["position"], value["company"]) for key, value in data["people"].items()]
[('Charlie', 'Company2', 'CEO'),
 ('Bob', 'Company1', 'CEO'),
 ('Alice', 'Company1', 'Manager')]

还有一系列公司,它们再次取消了dict的结构:

>>> companies = [item['name'] for item in data["companies"]]
['Company1', 'Company2']

现在查询非常简单,使用filter方法

def get_X_of_Y (x, y):
    return filter(lambda item: item[1]==x and item[2]==y, people)

所以你现在可以轻松搜索:

>>> get_X_of_Y("CEO", companies[0])
[('Bob', 'CEO', 'Company1')]

但是,如果你真的有成千上万的人和数百家公司,我仍然建议使用数据库。