Вот сценарий, который должен помочь Вам.
Уход, если у Вас есть только один элемент в последнем подсписке, я не знаю, как Вы хотите иметь дело с этим случаем. Я полагал, что элемент является результатом этого подсписка, но возможно Вы хотите проигнорировать последний подсписок или иметь 0 в результате.
Объяснения являются комментариями в сценарии:
# Initial list
l = [0, 10, 20, 5, 10, 30, 20, 35]
# Number of elements to consider in each sublist.
STEP = 3
# Get the size of the list
length = len(l)
# The result list, empty at the beginning, that will be populated by the differences
result_list = []
# Iterate through sublists of exactly STEP elements
i = 0
while (i+STEP-1)<length:
result_list.append(l[i+STEP-1]-l[i])
i += STEP
# Special case for the possible little last sublist
# No difference done and element is kept if there is only one element
if i==length-1:
result_list.append(l[-1])
# Else, do the difference in the last sublist
elif i<length-1:
result_list.append(l[-1]-l[i])
<час> Вот сценарий, который берет max-min
из каждого подсписка как OP, которую спрашивают, прежде всего:
l = [1,2,3,4,5,6,7,8]
n = 3
def chunks(l, n):
"""Yield successive n-sized chunks from l."""
for i in range(0, len(l), n):
yield l[i:i + n]
# Create the sublists
grouped_l = list(chunks(l,n))
# Do the max-min on each sublists
res = []
for i in grouped_l:
res.append(max(i)-min(i))
Вот и все: Запуск __call () в PHP, даже если метод существует
Просто объявите свои статические методы как protected
, чтобы они были недоступны вне класса, и получите магию __ callStatic ()
метод их вызова.
Изменить: ой, для этого вам понадобится 5.3 ...
Это один из примеров, когда вы можете отказаться от статических методов в пользу полиморфизма. Если бы ваш преобразователь данных был интерфейсом, вы могли бы иметь две реализации, одну для базы данных и одну для кэша памяти:
interface DataMapper {
public function getById($id);
// other data mapper methods
}
class DataMapper_DB implements DataMapper {
public function getById($id) {
// retrieve from db
}
// other methods
}
class DataMapper_Memcache implements DataMapper {
private $db;
public function __construct(DataMapper_DB $db, $host, ...) {
$this->db = $db;
// other set up
}
public function getById($id) {
// if in memcache return that
// else
$record = $this->db->getById($id);
// add record to memcache
return $record
}
//other methods
}
Думаю, вы могли бы сотворить магию с runkit , но вам нужно будет скомпилировать расширение из cvs, поскольку последняя версия не поддерживает 5.2.x
Пример:
<?php
/* Orig code */
class DataMapper {
static public function getById($value) {
echo "I'm " . __CLASS__ . "\n";
}
}
/* New Cache Mapper */
class DataMapper_Cache {
static public function getById($value) {
echo "I'm " . __CLASS__ . "\n";
}
}
// Running before rename and adopt
DataMapper::getById(12345);
// Do the renaming and adopt
runkit_method_rename('DataMapper', 'getById', 'getById_old');
runkit_class_adopt('DataMapper','DataMapper_Cache');
// Run the same code..
DataMapper::getById(12345);
?>
Output:
I'm DataMapper
I'm DataMapper_Cache