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

标签 python python-2.7 for-loop

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

class Person(object):
    def __init__(self, id, name):
        self.id = id
        self.name = name
        self.thisRate= None

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

然后我从一个文件中的数据加载了另一个数组,该文件包含 thisRate 的数据,其中大约有 13K,name 也没有排序:

person_data = []

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

person_data.append(row)

现在有了这两组数组,当它们之间的 name 匹配时,我将从 person_data 中分配 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 秒。

我的问题是,是否有更快或更好的方法来使用我拥有的 2 个数组实现相同的目的?

最佳答案

是的。制作一个从 namethisRate 的字典:

nd = {}

with open(<whatever>) as f:
    reader = csv.DictReader(<whatever>):
    for row in reader:
        nd[row['name']] = row['thisRate'] 

现在,使用这个字典对您的 Person 列表进行单次传递:

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

字典有一个 .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-catchStopIteration

关于python - 比循环查找数据更快或更好的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43244024/

相关文章:

python - 在数据库中搜索结构化数据(全文+查询)

Python:如何找到使levenshtein距离的字符的位置

c - 试图让这个 for 循环工作?

python - 如何使用 folium 使路线在 map 上的图层内可勾选

python - 如何从数据框列值创建多个列表

python - 无法访问嵌套字典元素python

python - Sympylambdafify与数组结合时出现错误

python - 在 Pandas 中动态命名 DataFrame

windows - 如何在 Windows 命令行中执行 for 循环?

c++ - 在 For 循环中使用 {} 且不使用 {} 的 If 语句