Проверка списка на соответствие различным критериям правил - PullRequest
1 голос
/ 10 февраля 2012

Учитывая список элементов, я хочу создать функцию, которая проверяет, соответствует ли она определенным критериям, и возвращает true или false.

Вот пример критериев и ожидаемого результата:

    #the to check against with criteria[1]
    langList = ['spanish','english','russian','persian']

    criteria = ['any'] #matches any language
    result: match

    #langList does not contain one or all
    criteria = ['any-but-or',[english,chinese]] 
    result: no match

    #langList does not contain all
    criteria = ['any-but-and',[english,chinese]] 
    result: match

    #langList contains one or all
    criteria = ['any-with-or',[english,chinese]] 
    result: match

    #langList contains all
    criteria = ['any-with-and',[english,chinese]] 
    result: no match

    #langList contains one or all and no others
    criteria = ['only-with-or',[english,chinese]] 
    result: no match

    #langList contains all and no others
    criteria = ['only-with-and',[english,chinese]] 
    result: no match

Какой лучший способ сделать это? Моя идея похожа на приведенную ниже, но я еще не освоил понимание списка, которое, я думаю, является ключевым здесь.

    def check_criteria_match(criteria, languageList):

        rule = criteria[0]
        criteriaLanguages = criteria[1]
        match = True

        if rule != 'any':
            continue
        elif rule = 'any-but-or' #check languageList:
            match = False; break

        #[...]

        return match

EDIT: Основываясь на ответе Правина Голлакота , вот последняя функция, не правда ли, она хорошенькая:)

def check_rule(rule, o, p):
    # o = original, p = pattern
    if rule == 'any':
        return True
    elif rule == 'any-but-or':
        return not bool(set(p)-set(o))
    elif rule == 'any-but-and':
        return len(set(p)-set(o)) != 0
    elif rule == 'any-with-or':
        return len(set(p)-set(o)) <= 1
    elif rule == 'any-with-and':
        return len(set(p)-set(o)) == 0
    elif rule == 'only-with-or':
        return len(set(o)-set(p)) <= 1
    elif rule == 'only-with-and':
        return len(set(o)-set(p)) == 0

Ответы [ 2 ]

3 голосов
/ 10 февраля 2012

Вы хотите провести тестирование членства, для которого sets являются подходящими структурами данных, а set операции работают хорошо.

Вы можете использовать наборы и лямбда-функции для построения диспетчера на основе правил, подобного этому.

>>> rule_checker = {'any': lambda o, p: True, 
...                 'any-but-or': lambda o, p: not bool(set(p) - set(o)),
...                 'any-but-and': lambda o, p: len(set(p) - set(o)) != 0,}

>>> lang_list = ['spanish','english','russian','persian']
>>> rule_checker['any-but-and'](lang_list, ['english','chinese'])
True
>>> rule_checker['any-but-or'](lang_list, ['english','chinese'])
False

Конечно, вам нужно добавить остальные правила.

РЕДАКТИРОВАТЬ: Вы также можете написать правила внутри функции, как это.

>>> def check_rule(rule, o, p):
...     # o = original, p = pattern
...     if rule == 'any':
...         return True
...     elif rule == 'any-but-or':
...         return not bool(set(p)-set(o))
...     elif rule == 'any-but-and':
...         return len(set(p)-set(o)) != 0
... 
>>> check_rule('any-but-and', lang_list, ['english','chinese'])
True
2 голосов
/ 10 февраля 2012

Вы можете использовать такую ​​библиотеку, как asq :

asq - это простая реализация LINQ -индуцированного API для Python, которая работает над итерациями Python, включая параллельную версию реализован в терминах многопроцессорной обработки стандартной библиотеки Python модуль. Эквивалентность спортивных функций API с LINQ для объектов, 100% справочный тест покрытия и исчерпывающая документация .

Примеры

>>> from asq.initiators import query
>>> langList = ['spanish', 'english', 'russian', 'persian']

# langlist contains 'russian'
>>> query(langList).contains('russian')
True

# langlist contains 'english' or 'italian'
>>> query(langList).any(lambda x : x == 'english' or x == 'italian')
True

# langlist contains 'english' and 'russian'
>>> not query(('english', 'russian')).difference(langList).any()
True
...