Решение на Четири функции от Йордан Джамбазов

Обратно към всички решения

Към профила на Йордан Джамбазов

Резултати

  • 6 точки от тестове
  • 0 бонус точки
  • 6 точки общо
  • 19 успешни тест(а)
  • 1 неуспешни тест(а)

Код

from functools import reduce, lru_cache
def groupby(func, seq):
res = reduce(lambda group, item: group.setdefault(func(item), [])
.append(item) or group, (item for item in seq), {})
return res
def iterate(func):
counter = 0
func_composer = lambda count: reduce(lambda f, g: lambda x:
f(g(x)), [func]*count)
def identity(*args, **kwargs):
if len(args) > 1:
return args
else:
return args[0]
while True:
if not counter:
yield identity
else:
yield func_composer(counter)
counter += 1
def zip_with(func, *iterables):
min_iter_length = len(min(iterables[:])) if iterables else 0
for i in range(min_iter_length):
res = func(*(iterable[i] for iterable in iterables))
yield res
def cache(func, cache_size):
@lru_cache(cache_size)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper

Лог от изпълнението

................E...
======================================================================
ERROR: test_zip_with_infinite_sequence (test.SecondHomeworkTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 60, in thread
    raise it.exc_info[1]
  File "lib/language/python/runner.py", line 48, in run
    self.result = func(*args, **kwargs)
  File "/tmp/d20130408-29081-unrbns/test.py", line 82, in test_zip_with_infinite_sequence
    self.assertEqual(expected, list(actual))
  File "/tmp/d20130408-29081-unrbns/solution.py", line 31, in zip_with
    min_iter_length = len(min(iterables[:])) if iterables else 0
TypeError: unorderable types: itertools.repeat() < list()

----------------------------------------------------------------------
Ran 20 tests in 0.011s

FAILED (errors=1)

История (2 версии и 2 коментара)

Йордан обнови решението на 12.03.2013 19:04 (преди около 11 години)

+from functools import reduce, lru_cache
+
+
+def groupby(func, seq):
+ res = reduce(lambda group, item: group.setdefault(func(item), [])
+ .append(item) or group, (item for item in seq), {})
+ return res
+
+
+def iterate(func):
+ count = 0
+
+ def wrapper(*args, **kwargs):
+ if not count:
+ return args[0]
+ else:
+ res = func(*args, **kwargs)
+ for _ in range(1, count):
+ res = func(res)
+ return res
+
+ while True:
+ yield wrapper
+ count += 1
+
+
+def zip_with(func, *iterables):
+ min_iter_length = len(min(iterables)) if iterables else 0
+
+ for i in range(min_iter_length):
+ res = func(*(iterable[i] for iterable in iterables))
+ yield res
+
+
+def cache(func, cache_size):
+ @lru_cache(cache_size)
+ def wrapper(*args, **kwargs):
+ return func(*args, **kwargs)
+
+ return wrapper

Можеш ли да се сетиш за iterable колекция, върху която не можеш да извикаш min?

iterate не ми харесва и може да се издъни в някои ситуации. Отдели му време

Идеята беше да си напишете кеш, не да ползвате този от functools. ;)

Йордан обнови решението на 15.03.2013 23:53 (преди около 11 години)

from functools import reduce, lru_cache
def groupby(func, seq):
res = reduce(lambda group, item: group.setdefault(func(item), [])
.append(item) or group, (item for item in seq), {})
return res
def iterate(func):
- count = 0
+ counter = 0
+ func_composer = lambda count: reduce(lambda f, g: lambda x:
+ f(g(x)), [func]*count)
- def wrapper(*args, **kwargs):
- if not count:
- return args[0]
+ def identity(*args, **kwargs):
+ if len(args) > 1:
+ return args
else:
- res = func(*args, **kwargs)
- for _ in range(1, count):
- res = func(res)
- return res
+ return args[0]
while True:
- yield wrapper
- count += 1
+ if not counter:
+ yield identity
+ else:
+ yield func_composer(counter)
+ counter += 1
+
def zip_with(func, *iterables):
- min_iter_length = len(min(iterables)) if iterables else 0
+ min_iter_length = len(min(iterables[:])) if iterables else 0
for i in range(min_iter_length):
res = func(*(iterable[i] for iterable in iterables))
yield res
def cache(func, cache_size):
@lru_cache(cache_size)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
- return wrapper
+ return wrapper

Преправих някои от нещата. iterate функцията я подобрих и използвам reduce за да имплементирам композициониране на функциите. Също така вече използвам slicing, за да обхождам елементите на итератора (спомена, че в някои случаи колекцията може да не се обходи и мисля, че това е решението). Използвах lru_cache от functools, защото ми се стори практично и интуитивно решение.