try: code except Exception: pass
Например, чтобы здесь не выскакивало исключение, а, например, элемент просто не включался в список.
[x[5] for x in y]
try: code except Exception: pass
[x[5] for x in y]
y=[(1,2,3,4,5,6),(1,2,3)] print filter(None,[x[5] if len(x)>=5 else None for x in y])
odnochlenВот такой вариант, правда не слишком изящный :(
А именно чтобы возвращался default или значение фильтровалось в случае эксепта?
def safe_get(x, n): try: return x[n] except IndexError: pass [safe_get(x, 5) for x in y]
def safe_call(callable, obj, default=None): try: return callable(obj) except Exception: return default [safe_call(lambda x: x[5], x, False) for x in y]
print [x[5] if len(x)>=5 else None for x in y] или print map(lambda x:(x[5] if len(x)>5 else None), y)
[f(x)[5] for x in y]
o7412369815963А я читал, что
try except для этого - плохой вариант, т.к. он медленный (относительно).
try: dic[x] except KeyError: #...
if x in dic: dic[x]
PooH-тся/-ться
или вот так даже, правда мне не нравиться, что ловятся все исключения
odnochlenЗакешировать результат, и отдавать его привызове.
Как избежать повторного вызова f()?
odnochlenОно быстрее если try-except использовать по назначению, т.е. для исключительных ситуаций, а т.к. мы разговариваем о сферическом коне, то лучший инструмент нельзя подобрать (нужно на конкретных данных)
А я читал, что
#!/usr/bin/python from timeit import Timer dim=[(1,2,3,4,5,6),(1,2,3)] * 100000 default = None def foo0(): for y in dim: try: x = y[5] except IndexError: x = default def foo1(): for y in dim: if len(y) > 5: x = y[5] else: x = default print Timer('test()', "from __main__ import foo0 as test").timeit(number=100) print Timer('test()', "from __main__ import foo1 as test").timeit(number=100) dim = [{ 5:0 }, {}] * 100000 def bar0(): for y in dim: try: x = y[5] except KeyError: x = default def bar1(): for y in dim: x = y.get(5, default) print Timer('test()', "from __main__ import bar0 as test").timeit(number=100) print Timer('test()', "from __main__ import bar1 as test").timeit(number=100)
9.03296399117 2.14645504951 8.65659809113 2.97780108452
odnochlenЭто опять же зависит от задачи, разделение исключений на допустимые и не допустимые.
Так уже ближе. А что с того, что ловится все?
o7412369815963Не-а, я имею в виду, чтобы не вызывать ее 2 раза за один цикл. Что если там readline()?
Закешировать результат, и отдавать его привызове.
o7412369815963Да, но опять же, это часто игнорируют, а в питоне ожидаемые исключения можно выковырять только из документации или исходников.
Это опять же зависит от задачи, разделение исключений на допустимые и не допустимые.
Например при получении данных от сервера можно игнорировать “кривые данные”, но если сервер не доступен, то сообщить об этом “на верх”.
o7412369815963Ах да, в питоне же break с меткой нету.
А вообще raise - это метод передачи управления в другое место “напрямую”. Например можно в сложной рекурсивной ф-ии вернуть результат “на верх”: raise Result(5), вместо кучи return-ов.