Сложное понимание списка в Python - PullRequest
0 голосов
/ 04 марта 2020

У меня есть список записей в mylist , и я хочу перебирать список, пока не найду первую запись , которая удовлетворяет всем 3 правилам в моих правилах список. Я пытаюсь использовать понимание вложенного списка, поскольку я думал, что это будет быстрее, чем вложенное для l oop, однако моя логика c немного сложна, и я не уверен, возможно ли понимание списка. Вот мой код:

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, то понимание списка приведет к неверным результатам. Я думаю, именно поэтому это занимает больше времени, чем вложенное для l oop. Возможно ли даже преобразовать это вложенное для l oop в понимание вложенного списка? спасибо

1 Ответ

2 голосов
/ 04 марта 2020

Понимание списка происходит быстрее, когда вы на самом деле строите список, и лишь незначительно ( source ). В вашем случае вы только делаете поиск. Вложенные циклы for не только будут быстрее, но и сделают ваш код более читабельным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...