Использование списочных представлений и исключений? - PullRequest
3 голосов
/ 02 июня 2009

Хорошо, допустим, у меня есть список, и я хочу проверить, существует ли этот список в другом списке. Я могу сделать это следующим образом:

all(value in some_map for value in required_values)

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

Мне более или менее любопытно, кажется, все признаки указывают на нет.

РЕДАКТИРОВАТЬ Argh Я имел в виду это:

for value in required_values:
 if value not in some_map:
  raise somecustomException(value)

Глядя на них, я не вижу, как найти значение, в котором произошла ошибка

Ответы [ 6 ]

14 голосов
/ 02 июня 2009

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

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

2 голосов
/ 02 июня 2009

Вы не можете использовать повышение в понимании списка. Вы можете проверить сами, взглянув на грамматику в Справочнике по языку Python .

Однако вы можете вызвать функцию, которая вызывает исключение для вас.

2 голосов
/ 02 июня 2009

Если вы не хотите рассматривать дубликаты и значения могут быть хэшируемыми, используйте наборы. Они проще, быстрее и могут извлекать «все» элементы, отсутствующие в одной операции:

required_values = set('abc') # store this as a set from the beginning
values = set('ab')
missing = required_values - values
if missing:
    raise SomeException('The values %r are not in %r' % 
                        (missing, required_values))
0 голосов
/ 29 сентября 2017

Мне было интересно сегодня вечером. Мой вариант использования - перебирать список объектов и выдавать ошибку, когда объект не был определенного типа. Мое решение - использовать генератор.

def iter_my_class(my_class_list):
    for c in my_class_list:
        if not isinstance(c, MyClass):
            raise ValueError('Expected MyClass')
        yield c

Затем используется как

classes = [c for c in iter_my_class(my_class_list)]

Я написал это на моем телефоне. Если это без ошибок, вы все должны мне пива.

0 голосов
/ 02 июня 2009

Другая (безобразная) возможность - функция error_on_false:

def error_on_false(value)
    if value:
        return value
    else:
        raise Exception('Wrong value: %r' % value)

if all(error_on_false(value in some_map) for value in required_values):
    continue_code()
    do_something('...')

Это ужасно. Я бы использовал set вместо.

0 голосов
/ 02 июня 2009

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

def has_required(some_map, value):
  if not value in some_map:
    raise RequiredException('Missing required value: %s' % value)

all(has_required(some_map, value) for value in required_values)
...