Следующее намного быстрее:
f <- function(x){
log2(bitwAnd(x,-x))
}
Для сравнения:
g <- function(x){
unlist(lapply(x, function(z) min(which(as.integer(intToBits(z)) == 1))-1))
}
Быстрый тест:
> library(microbenchmark)
> tests <- floor(runif(1000,1,2^31))
> sum(f(tests) == g(tests)) #just to check
[1] 1000
> microbenchmark(f(tests),g(tests))
Unit: microseconds
expr min lq mean median uq max neval
f(tests) 38.435 40.5515 45.82673 42.667 45.1355 146.337 100
g(tests) 1985.940 2083.9680 2530.79036 2131.218 2287.4280 11749.204 100
Python является языком, который может быть описан как:
"правила можно поместиться в ладонь руки с огромным мешком рычагов".
Почти все в Python следует тем же простым стандартам. Все доступно, изменяемо, и tweakable. Существует очень немного элементов уровня языка.
Берут, например, len (данные) встроенная функция. len(data)
работы путем простой проверки на data.__len__()
метод, и затем называет его и возвращает значение. Тот путь, len()
может работать над любым объектом, который реализует __len__()
метод.
Запускаются путем приобретения знаний о типах и базовом синтаксисе:
Затем движение к приобретению знаний о том, как Python работает:
dir()
, функция __builtins__
, После того как у Вас есть понимание того, как соответствовать, соединяет, возвратитесь и покройте некоторые более усовершенствованные функции языка:
__len__
(существуют тонны их) И после того как у Вас есть уровень комфорта с этими объектами (с вниманием на то, что делает их pythonic), посмотрите на более определенные объекты:
И никогда не забывают Дзэн Python (Tim Peters)
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
Эта страница покрывает все главные идиомы Python: http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html
Важная идиома в Python является docstrings.
Каждый объект имеет __ документ __ атрибут, который может использоваться для получения справки на том объекте. Можно установить __ документ __ атрибут на модулях, классах, методах и функциях как это:
# this is m.py
""" module docstring """
class c:
"""class docstring"""
def m(self):
"""method docstring"""
pass
def f(a):
"""function f docstring"""
return
Теперь, когда Вы тип help(m)
, help(m.f)
и т.д. это распечатает docstring как сообщение справки.
, поскольку это - просто часть самоанализа обычного объекта, это может использоваться documention генерация систем как epydoc или использоваться для тестирования unittest.
Это может также быть помещено в более нетрадиционный (т.е. неидиоматичное) использование, такое как грамматики в Dparser.
то, Где это становится еще более интересным мне, - то, что, даже при том, что документ является атрибутом "только для чтения" на большинстве объектов, можно использовать их где угодно как это:
x = 5
""" pseudo docstring for x """
и инструменты документации как epydoc может взять их и отформатировать их правильно (в противоположность нормальному комментарию, который остается в форматировании кода.
Декораторы получают мой голос. Где еще может Вы писать что-то как:
def trace(num_args=0):
def wrapper(func):
def new_f(*a,**k):
print_args = ''
if num_args > 0:
print_args = str.join(',', [str(x) for x in a[0:num_args]])
print('entering %s(%s)' %(f.__name__,print_args))
rc = f(*a,**k)
if rc is not None:
print('exiting %s(%s)=%s' %(f.__name__,str(rc)))
else:
print('exiting %s(%s)' %(f.__name__))
return rc
return new_f
return wrapper
@trace(1)
def factorial(n):
if n < 2:
return 1
return n * factorial(n-1)
factorial(5)
и производятся как:
entering factorial(5)
entering factorial(4)
entering factorial(3)
entering factorial(2)
entering factorial(1)
entering factorial(0)
exiting factorial(0)=1
exiting factorial(1)=1
exiting factorial(2)=2
exiting factorial(3)=6
exiting factorial(4)=24
exiting factorial(5)=120
Все подключенное к использованию списка.
Понимания, генераторы, и т.д.
С более усовершенствованной точки зрения, понимая, как словари используются внутренне Python. Классы, функции, модули, ссылки - все просто свойства на словаре. После того как это понято, легко понять, как обезьяне исправляют и используют мощное __ gettattr __, __ setattr __, и __ вызов __ методы.
Вот тот, который может помочь. Что является различием между:
[ foo(x) for x in range(0, 5) ][0]
и
( foo(x) for x in range(0, 5) ).next()
ответ: во втором примере нечто называют только однажды. Это может быть важно, если нечто имеет побочный эффект, или если повторяемое, используемое создать список, является большим.
Лично, мне действительно нравится синтаксис Python, определяющий блоки кода при помощи , добавление отступа , а не словами "НАЧИНАЕТСЯ" и "ЗАКАНЧИВАЕТСЯ" (как в Основном и Visual Basic Microsoft - мне не нравятся они) или при помощи лево-и правых фигурных скобок (как в C, C++, Java, Perl - мне нравятся они).
Это действительно удивило меня, потому что, хотя добавление отступа всегда было очень важно для меня, я не сделал к большому количеству "шума" об этом - я жил с ним, и это считают навыком, чтобы быть в состоянии считать другие народы, код "спагетти". Кроме того, я никогда не слышал, что другой программист предложил делать добавление отступа частью языка. До Python! Мне только жаль, что я не осознал эту идею сначала.
мне, это - как будто синтаксис Python вынуждает Вас написать хороший, читаемый код.
Хорошо, я выйду из своей мыльницы.;-)
Используя строковые замены:
name = "Joe"
age = 12
print "My name is %s, I am %s" % (name, age)
, Когда я не программирую в Python, что простое использование - то, что я пропускаю больше всего.
Двумя вещами, которые показались мне особенно Pythonic, был динамический контроль типов и различные разновидности списков, используемых в Python, особенно кортежи.
навязчивая идея списка Python, как могли говорить, была LISP-y, но она имеет свою собственную уникальную разновидность. Строка как:
return HandEvaluator.StraightFlush, (PokerCard.longFaces[index + 4],
PokerCard.longSuits[flushSuit]), []
или даже
return False, False, False
просто похож на Python и ничто иное. (Технически, Вы видели бы последнего в Lua также, но Lua является симпатичный Pythonic в целом.)
Другая вещь, которую Вы не можете запустить достаточно рано, вероятно, тестирует. Здесь особенно doctests являются отличным способом тестирования Вашего кода путем объяснения этого одновременно.
doctests являются простым текстовым файлом, содержащим интерактивную сессию интерпретатора плюс текст как это:
Let's instantiate our class::
>>> a=Something(text="yes")
>>> a.text
yes
Now call this method and check the results::
>>> a.canify()
>>> a.text
yes, I can
, Если, например, a.text возвращает что-то другое, тест перестанет работать.
doctests могут быть внутренними docstrings или автономными текстовыми файлами и выполняются при помощи doctests модуль . Конечно, более известные модульные тесты также доступны.