Это непосредственно не отвечает на Ваш вопрос (вообще), но я использовал MurmurHash прежде для генерации хешей: Предположение murmurhash
я должен объяснить почему: murmurhash чертовски быстр...
Написание метода foreach
не очень питонично. Вам лучше сделать его итератором, чтобы он работал со стандартными функциями Python, такими как min
.
Вместо того, чтобы писать что-то вроде этого:
def foreach(self, f):
for d in self._data:
f(d)
напишите следующее:
def __iter__(self):
for d in self._data:
yield d
Теперь вы можете вызвать min
как min (myobj)
.
Python имеет встроенный поддержка поиска минимумов :
>>> min([1, 2, 3])
1
Если вам нужно сначала обработать список с помощью функции, вы можете сделать это с помощью map :
>>> def double(x):
... return x * 2
...
>>> min(map(double, [1, 2, 3]))
2
Или вы можете поработать с ] составить список и выражения генератора , например:
>>> min(double(x) for x in [1, 2, 3])
2
You can't do this with foreach
and a lambda. If you want to do this in a functional style without actually using min
, you'll find reduce
is pretty close to the function you were trying to define.
l = [5,2,6,7,9,8]
reduce(lambda a,b: a if a < b else b, l[1:], l[0])
I have foreach function which calls specified function on every element which it contains
It sounds, from the comment you subsequently posted, that you have re-invented the built-in map
function.
It sounds like you're looking for something like this:
min(map(f, seq))
where f
is the function that you want to call on every item in the list.
As gnibbler shows, if you want to find the value x
in the sequence for which f(x)
returns the lowest value, you can use:
min(seq, key=f)
...unless you want to find all of the items in seq
for which f
returns the lowest value. For instance, if seq
is a list of dictionaries,
min(seq, key=len)
will return the first dictionary in the list with the smallest number of items, not all dictionaries that contain that number of items.
To get a list of all items in a sequence for which the function f
returns the smallest value, do this:
values = map(f, seq)
result = [seq[i] for (i, v) in enumerate(values) if v == min(values)]
Хорошо, вам нужно понять одну вещь: лямбда
создает для вас объект функции. Но то же самое и с обычным def
. Посмотрите на этот пример:
lst = range(10)
print filter(lambda x: x % 2 == 0, lst)
def is_even(x):
return x % 2 == 0
print filter(is_even, lst)
Оба эти действия работают. Они дают одинаковый идентичный результат. лямбда
создает безымянный объект функции; def
создает именованный функциональный объект. filter ()
не заботится о том, имеет ли объект функции имя или нет.
Итак, если ваша единственная проблема с лямбда
, то вы не можете использовать =
в лямбда
, вы можете просто создать функцию, используя def
.
Теперь, при этом, я не предлагаю вам использовать ваш .foreach ()
метод поиска минимального значения. Вместо этого сделайте так, чтобы ваш основной объект возвращал список значений, и просто вызовите функцию Python min ()
.
lst = range(10)
print min(lst)
РЕДАКТИРОВАТЬ: Я согласен с тем, что принятый ответ лучше. Вместо того, чтобы возвращать список значений, лучше определить __ iter __ ()
и сделать объект повторяемым.
Предположим, у вас есть
>>> seq = range(-4,4)
>>> def f(x):
... return x*x-2
для минимального значения f
>>> min(f(x) for x in seq)
-2
для минимального значения x
>>> min(seq, key=f)
0
, конечно, вы также можете использовать лямбда
>>> min((lambda x:x*x-2)(x) for x in range(-4,4))
-2
, но это немного уродливо, карта здесь выглядит лучше
>>> min(map(lambda x:x*x-2, seq))
-2
>>> min(seq,key=lambda x:x*x-2)
0