Форум сайта python.su
Здравствуйте, давно интересовался, имеет ли право на существования форма записи условий, рассмотренная мною ниже.
Есть прогромма, которая имеет два списка: exc_list- отвечает за список сайтов, type_list- флаг, который определяет с каким типом списка мы сейчас работаем. Если type_list = 0, то это белый список, type_list = 1 черый. В зависимости от типа списка, мы должны разрешать или запрещать переход по url'у. Вот как это должно выглядеть:
exc_list = [u'mail.ru',u'yandex.ru',u'google.com',u'rambler.ru']
type_list = 1
host = u'rambler.ru'
if type_list:
# Black List
if host in exc_list:
print u'close'
else:
print u'connect'
else:
# White list
if host in exc_list:
print u'connect'
else:
print u'close'
if (host in exc_list and type_list) or (not host in exc_list and not type_list):
print u'close'
else:
print u'connect'
if ((None,True),(True,None))[type_list][host in exc_list]:
print u'connect'
else:
print u'close'
Офлайн
Думаю самый нормальный вариант, конечно если я ничего не напутал :)
if type_list ^ host in exc_list:
print u'close'
else:
print u'connect'
Офлайн
Получаю ошибку:
TypeError: unsupported operand type(s) for ^: 'int' and 'unicode'
Офлайн
Тогда вот так:
if type_list ^ int(host in exc_list):
print u'connect'
else:
print u'close'
from timeit import Timer
t = Timer('''
exc_list = [u'mail.ru',u'yandex.ru',u'google.com',u'rambler.ru']
type_list = 1
host = u'rambler.ru'
if type_list:
# Black List
if host in exc_list:
pass
else:
pass
else:
# White list
if host in exc_list:
pass
else:
pass
''')
print t.timeit(100)
t = Timer('''
exc_list = [u'mail.ru',u'yandex.ru',u'google.com',u'rambler.ru']
type_list = 1
host = u'rambler.ru'
if (host in exc_list and type_list) or (not host in exc_list and not type_list):
pass
else:
pass
''')
print t.timeit(100)
t = Timer('''
exc_list = [u'mail.ru',u'yandex.ru',u'google.com',u'rambler.ru']
type_list = 1
host = u'rambler.ru'
if ((None,True),(True,None))[type_list][host in exc_list]:
pass
else:
pass
''')
print t.timeit(100)
t = Timer('''
exc_list = [u'mail.ru', u'yandex.ru', u'google.com', u'rambler.ru']
type_list = 0
host = u'rambler.ru'
if type_list ^ int(host in exc_list):
pass
else:
pass
''')
print t.timeit(100)
Отредактировано (Авг. 21, 2009 16:06:24)
Офлайн
Спасибо, именно такого ответа я и ждал!
Офлайн
Не обязательно приводить к инту, можно просто type_list ^ (host in exc_list).
На счёт скорости тоже можно поспорить, поскольку второй вариант даёт больший разброс по времени выполнения в зависимости от данных, и выигрывает у моего варианта только в 1 случае из 4 :) .
(host in exc_list and type_list) or (not host in exc_list and not type_list)
5.41210174561e-05
0.000151872634888
8.29696655273e-05
8.29696655273e-05
type_list ^ (host in exc_list)
5.48362731934e-05
5.69820404053e-05
6.19888305664e-05
5.91278076172e-05
Офлайн
Мне второй вариант нравиться больше всего.
Только надо его изменить.
if (type_list and host in exc_list) or (not type_list and not host in exc_list):
print u'close'
else:
print u'connect'
Офлайн
Я бы сделал так:
def check_host(host, host_list, list_type='black'):
"""
>>> check_host('mail.ru', ['mail.ru', 'yandex.ru'], 'white')
'connect'
>>> check_host('python.su', ['mail.ru', 'yandex.ru'], 'white')
'close'
>>> check_host('mail.ru', ['mail.ru', 'yandex.ru'], 'black')
'close'
>>> check_host('python.su', ['mail.ru', 'yandex.ru'], 'black')
'connect'
"""
assert list_type in ('black', 'white')
actions = {
# (host in hostlist, is_whitelist): action
(True, 'white'): 'connect',
(False, 'white'): 'close',
(False, 'black'): 'connect',
(True, 'black'): 'close',
}
action = actions.get((host in host_list, list_type))
return action
Отредактировано (Авг. 24, 2009 10:11:57)
Офлайн