Python 比循环查找数据更快或更好的方法?

Python 比循环查找数据更快或更好的方法?,python,python-2.7,for-loop,Python,Python 2.7,For Loop,我有一个类Person的对象数组,如下所示,thisRate首先设置为None: 我将大约21K个Person对象加载到一个数组中,名称未排序 然后,我从一个文件中的数据加载了另一个数组,该文件包含该速率的数据,其中约13K个,名称也未排序: person_data = [] # read from file row['name'] = 'Peter' row['thisRate'] = '0.12334' person_data.append(row) 现在有了这两组数组,当名称在它们之

我有一个类Person的对象数组,如下所示,thisRate首先设置为None:

我将大约21K个Person对象加载到一个数组中,名称未排序

然后,我从一个文件中的数据加载了另一个数组,该文件包含该速率的数据,其中约13K个,名称也未排序:

person_data = []

# read from file
row['name'] = 'Peter'
row['thisRate'] = '0.12334'

person_data.append(row)
现在有了这两组数组,当名称在它们之间匹配时,我将把person_数据中的thisRate分配给person.thisRate

我所做的是这样一个循环:

for person in persons:
    data = None
    try:
        data = next(personData for personData in person_data
                        if personData['name'] == person.name)
    except StopIteration:
        print("No rate for this person: {}".format(person.name))

    if data:
        person.thisRate = float( data['thisRate'] )
这个环路

data = next(personData for personData in person_data
                if personData['name'] == person.name)
运行良好,使用Python 2.7.13在我的机器上使用21秒


我的问题是,有没有更快或更好的方法来实现我拥有的两个阵列的相同功能?

是的。制作一本从name到thisRate的字典:

字典有一个.get方法,它允许您在关键字不在dict中的情况下提供一个默认值。我使用了None,它实际上是默认值,但您可以使用任何您想要的

这是一个线性时间解。您的解决方案是二次时间,因为您基本上在做:

for person in persons:
    for data in person_data:
        if data['name'] == person.name:
            person.thisRate = data['thisRate']
            break
    else:
        print("No rate for this person: {}".format(person.name))

只是以一种模糊了生成器表达式内部基本嵌套的for循环的方式,对于生成器表达式来说这并不是一个好的用例,您应该首先使用for循环,然后您就不必处理try-catch-StopIteration了

是的。制作一本从name到thisRate的字典:

字典有一个.get方法,它允许您在关键字不在dict中的情况下提供一个默认值。我使用了None,它实际上是默认值,但您可以使用任何您想要的

这是一个线性时间解。您的解决方案是二次时间,因为您基本上在做:

for person in persons:
    for data in person_data:
        if data['name'] == person.name:
            person.thisRate = data['thisRate']
            break
    else:
        print("No rate for this person: {}".format(person.name))

只是以一种模糊的方式,在生成器表达式中基本上嵌套了for循环,这对生成器表达式来说不是一个很好的用例,您应该首先使用for循环,然后您不必处理try catch a StopIteration,当您说array时,您是指列表吗?是的列表,在帖子中编辑。当你说数组时,是指列表吗?是的,列表,在帖子中编辑。try-catch用于报告没有数据的人,以便稍后采取进一步行动,例如提供此人的丢失率。@StevenYong,可以用替换。因此,next+genexpr不需要引发StopIteration。下一步可以传递genexpr和一个默认参数(如果未找到命中):如果personData['name']==person.name,则person数据中personData的nextpersonData,无这是一个完全有效的用例。@StevenYong看看我是如何用if thisRate为None修改for循环的,看看你如何处理没有相应名称的情况…@StevenYong:请注意,使用next并不能在这里保存任何东西,它不会使你的代码更快。我只是指出,如果不是使用错误的算法,下一步就可以了;您不需要通过StopIteration来处理它。try-catch用于报告没有数据的人,以便稍后采取进一步的行动,例如提供此人的丢失率。@StevenYong,可以替换为。因此,next+genexpr不需要引发StopIteration。下一步可以传递genexpr和一个默认参数(如果未找到命中):如果personData['name']==person.name,则person数据中personData的nextpersonData,无这是一个完全有效的用例。@StevenYong看看我是如何用if thisRate为None修改for循环的,看看你如何处理没有相应名称的情况…@StevenYong:请注意,使用next并不能在这里保存任何东西,它不会使你的代码更快。我只是指出,如果不是使用错误的算法,下一步就可以了;您不需要通过StopIteration来处理它。
for person in persons:
    thisRate = nd.get(person.name, None)
    person.thisRate = thisRate
    if thisRate is None:
        print("No rate for this person: {}".format(person.name))
for person in persons:
    for data in person_data:
        if data['name'] == person.name:
            person.thisRate = data['thisRate']
            break
    else:
        print("No rate for this person: {}".format(person.name))