список питонов, который соответствует всему - PullRequest
1 голос
/ 07 января 2010

Я, вероятно, не правильно спросил: мне бы хотелось, чтобы значение списка совпадало с любым списком: обратное значение (None,) но даже с (None,) он будет соответствовать элементу как None (что мне не нужно)

Дело в том, что у меня есть функция, работающая с: [x for x in my_list if x[field] not in filter_list]

и я хотел бы отфильтровать все или ничего без проведения тестов, таких как: if filter_list==(None,): return [] и if filter_list==('*',): return my_list

PS: я хотел упростить свой вопрос, приводящий к некоторым ошибкам (list идентификатор) или глупости [x for x in x];)


Привет

Мне нужно сделать некоторую фильтрацию со списком в Python.

если я сделаю что-то подобное:

[x for x in list if x in (None,)]

Я избавляюсь от всех ценностей, что нормально

но я бы хотел, чтобы одно и то же совпадало со всеми

Я могу сделать что-то вроде:

[x for x in list if x not in (None,)]

но оно не будет однородным с остальными

Я пробовал некоторые вещи, но, например, (True,) соответствует только 1

Обратите внимание, что значения для фильтрации являются числовыми, но если у вас есть что-то общее (например, (None,), чтобы ничего не соответствовать), было бы здорово

Спасибо Louis

Ответы [ 7 ]

5 голосов
/ 07 января 2010

__contains__ - магический метод, который проверяет, есть ли что-то в последовательности:

class everything(object):
    def __contains__(self, _):
        return True           

for x in (1,2,3):
    print x in everything()
4 голосов
/ 07 января 2010

Лучший синтаксис будет:

[x for x in lst if x is None]
[x for x in lst if x is not None]
3 голосов
/ 07 января 2010

Вы можете изменить свою программу так, чтобы она принимала объект фильтра вместо списка.

Абстрактный базовый фильтр будет иметь метод matches, который возвращает true, если x * соответствует ".

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

Вы также можете иметь два специальных подкласса объекта фильтра: none и all.

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

3 голосов
/ 07 января 2010

Что вы подразумеваете под

Я бы хотел, чтобы все совпадало

Просто сделай

[x for x in list]

и каждый элемент в list соответствует.

0 голосов
/ 07 января 2010

Отвечая на ваш исправленный вопрос: список, который «соответствует» всем возможным значениям, фактически бесконечной длины. Таким образом, вы не можете делать то, что хотите, без теста if. Я предлагаю, чтобы ваш аргумент arg был либо списком, либо одним из двух значений, представляющих регистры «all» и «none»:

FILTER_NONE = object() # or []
FILTER_ALL = object()

def filter_func(alist, filter_list):
    if filter_list is FILTER_ALL:
        return []
    elif filter_list is FILTER_NONE:
        return alist
        # or maybe alist[:] # copy the list
    return [x for x in alist if x not in filter_list]

Если filter_list большой, вы можете заменить последнюю строку на:

    filter_set = set(filter_list)
    return [x for x in alist if x not in filter_set]

В качестве альтернативы, не беспокойтесь; просто документируйте, что filter_list (переименованный в filter_collection) может быть чем угодно, поддерживающим __contains__(), и напоминать читателям, что наборы будут работать быстрее списков.

0 голосов
/ 07 января 2010

но я бы хотел иметь то же самое вещь, чтобы соответствовать всему

Чтобы соответствовать всему, вам не нужно выражение if

[x for x in list1]

или если вы действительно любите делать

[x for x in list1 if x in [x]]
0 голосов
/ 07 января 2010

Вам не нужно if, вы можете просто сказать

[x for x in list]
...