【问题标题】:Complex List Comprehension in PythonPython中的复杂列表理解
【发布时间】:2020-03-04 18:36:51
【问题描述】:

我在 mylist 中有一个记录列表,我想遍历该列表,直到在我的 rules 中找到满足所有 3 个规则的 first record 列表。我正在尝试使用嵌套列表推导,因为我认为它比嵌套 for 循环更快,但是,我的逻辑有点复杂,我不确定列表推导是否可行。这是我的代码:

import operator
import timeit


def check(rec, vl, op, vr):
    operations = {'>': operator.gt,
                  '<': operator.lt,
                  '>=': operator.ge,
                  '<=': operator.le,
                  '=': operator.eq,
                  '!=': operator.ne}
    return operations[op](vl, vr)


mylist = [{'criteria': {'shipping_point': '3000', 'from_tot_weight': '250', 'to_tot_weight': '999999'}, 'result': {'ship_type': '02'}}, {'criteria': {'shipping_point': '3200', 'from_tot_weight': '350', 'to_tot_weight': '999999'}, 'result': {'ship_type': '02'}}]

rules = [{'varL': ['rec', 'criteria', 'shipping_point'], 'operator': '=', 'varR': "3000"},
         {'varL': ['rec', 'criteria', 'from_tot_weight'], 'operator': '<=', 'varR': "250"},
         {'varL': ['rec', 'criteria', 'to_tot_weight'], 'operator': '>=', 'varR': "250"}]



def run_1():
    newlist = [rec for rec in mylist if all(check(rec, locals()[rule['varL'][0]][rule['varL'][1]][rule['varL'][2]],
                                                   rule['operator'],
                                                   rule['varR'])
                                             for rule in rules)]
    print(newlist)

def run_2():
    found = False
    result = []
    for rec in mylist:
        for rule in rules:
            if check(rec, locals()[rule['varL'][0]][rule['varL'][1]][rule['varL'][2]],
                                   rule['operator'],
                                   rule['varR']):
                found = True
            else:
                found = False
                break
        if found:
            result = rec
            break
    print(result)

run_count = 1
print("==========List Comprehension with Locals()==========")
print(timeit.timeit(run_1, number=run_count))
print(" ")
print("==========Nested for loops==========================")
print(timeit.timeit(run_2, number=run_count))

在这段代码中,当我找到满足 rules 列表中所有规则的记录时,我的列表理解不会停止。实际上,如果您将 mylist 中的两条记录都更改为 shipping_point = 3000,那么列表推导会产生不正确的结果。我认为这就是为什么它比嵌套的 for 循环需要更长的时间。甚至可以将此嵌套的 for 循环转换为嵌套的列表理解吗?谢谢

【问题讨论】:

  • “我正在尝试使用嵌套列表推导,因为我认为它比嵌套 for 循环更快” - 列表推导并不神奇;它们的工作方式与循环完全相同,只是语法不同。性能差异将是微不足道的。

标签: python list-comprehension operator-keyword


【解决方案1】:

只有在您实际构建列表时,列表理解才会更快,而且只是稍微快一点 (source)。在您的情况下,您只是在进行查找。嵌套的 for 循环不仅会更快,还会让您的代码更具可读性。

【讨论】:

  • 感谢您的回复。我对嵌套 for 循环的唯一担心是某些列表中可能有超过 20 万条记录。你觉得这有什么问题吗?使用带有一些选择标准的列表推导创建列表的子集,然后遍历过滤的列表以应用规则是否有意义。例如,如果列表中有 200k 条记录,其中 100k 用于 shipping_point 3000,而另外 100k 用于 shipping_point 4000,那么我可以使用列表理解创建一个仅包含 3000 条的新列表,然后遍历它们以应用规则。想法?
  • @TonyRaimo - 列表理解无论如何都是一个 for 循环。它只是 simple for 构建列表的循环的语法糖。使用 200K 元素列表时可能会遇到很多问题,但我认为 for-loop 与 list-comprehension 并不能解决任何问题。
猜你喜欢
  • 1970-01-01
  • 2022-11-23
  • 1970-01-01
  • 2021-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-15
  • 2021-04-20
相关资源
最近更新 更多