Python 2.6:如何有效地比较一个特定字段上同一对象类型的两个列表



我有一个名为" UserDatabaseRecord"的类。它有许多字段,例如"用户名"," expiration_date"等。

我有两个userDatabaseRecord对象的列表:列表A和列表B

我想验证列表a中的所有userDatabaseRecords,用户名字段与列表中的任何userDatabaseRecords用户名匹配b。

我能够非常效率地完成此操作:

for record_a in List_A:
   for record_b in List_B:
      if record_a.username == record_b.username:
         print "Duplicate username: {0}".format(record_a.username)

我想它有效。我只是想让它更有效和/或" Pythonic"。

这个问题是相关的,但最终我不知道如何将其应用于对象的列表时,仅在一个字段上进行比较:单线仪检查是否至少一个项目列表存在于另一个列表中?

问题是,对于列表A中的每个元素,您都在列表B中检查所有元素。因此,如果列表的长度为n和m,则那是n*m比较。

如果您从列表B中制作了一组用户名,则可以在其上使用in运算符 - 这不仅更简单,而且是瞬时的,而不必一一检查所有值。因此,您只需要n查找而不是n*m。

so:

b_names = {record.username for record in List_B}
for record_a in List_A:
    if record_a.username in b_names:
        print "Duplicate username: {0}".format(record_a.username)

或更简单,使用集合:

a_names = {record.username for record in List_A}
b_names = {record.username for record in List_B}
for name in a_names & b_names:
    print "Duplicate username: {0}".format(name)

实际上,您不需要两个设置,您可以使用发电机表达式将一个组合成一个集合,而另一个则只是一个迭代器:

a_names = {record.username for record in List_A}
b_names = (record.username for record in List_B)
for name in a_names.intersection(b_names):
    print "Duplicate username: {0}".format(name)

其中一个可能比其他速度快一点,但是它们都会在同一球场上 - 更重要的是,它们都是线性的,而不是二次。因此,我建议使用哪个对您来说最有意义。

如果您只需要知道是否有重复的而不是获取它们的列表,或者只需要任意获得重复项而不是全部获得重复项,则可以通过早期的"短路"来加快它的速度 - 例如,在第一个print之后添加break,或在最后一个中使用isdisjoint而不是intersection

您可以尝试以下操作:

for rec_a, rec_b in zip(List_A, List_B):
    if rec_a == rec_b:
        print "Duplicate username: {0}".format(rec_a.username)

相关内容

  • 没有找到相关文章

最新更新