Рассмотрим следующий код, который является неотъемлемой частью моих вопросов ниже:
import functools
N = 3
class Struct:
"""Create an instance with argument=value slots.
This is for making a lightweight object whose class doesn't matter."""
def __init__(self, **entries):
self.__dict__.update(entries)
def __repr__(self):
args = ['%s=%s' % (k, repr(v)) for (k, v) in vars(self).items()]
return '\nStruct(%s)' % ', '.join(args)
def doit( move ):
( rowIn, colIn ) = move
something = rowIn + ( 10 * colIn ) # An involved computation here in real life
return Struct( coord = ( rowIn, colIn ), something = something )
legalStates = [ ( row, col ) for row in xrange( N ) for col in xrange( N ) ] # A more complicated function that generates the list in real life. Call it 'complicatedFunction'
genExpFn = lambda : ( ( s.something, m, s ) for ( m, s ) in ( ( move, doit( move ) ) for move in legalStates ) ) #Q1
successorsSortedGenFn = lambda : ( p for p in sorted( genExpFn(), reverse = True ) )
def bFunc( s, a ):
#print "a * s ->", a * s
return a * s # An involved computation here in real life
def aFunc( ( v, m, s ) ): #Q2
assert( s.something == v )
return bFunc( s.something, 10 )
print "min( successorsSortedGen ) -> " + str( min( successorsSortedGenFn(), key=functools.partial( aFunc )) ) #Q3
print
print "max( successorsSortedGen ) -> " + str( max( successorsSortedGenFn(), key=functools.partial( aFunc )) ) #Q4
Мои вопросы основаны на утверждениях, помеченных как "#Q":
Q1 : Очевидно, что генератор полностью создан (все элементы выполнены), так как мы вызываем для него sorted()
(который генерирует все элементы и создает временный несортированный список, который он сортирует и возвращает как новый список?).
Есть ли эффективный для пространства способ, который минимизирует создание временных файлов и дает отсортированный список?
Я пытался, но не смог написать понимание списка, которое могло бы сортировать вplace with list.sort()
Это было то выражение, о котором я думал:
successorsSorted = [ ( s.something, m, s ) for ( m, s ) in ( ( move, doit( move ) ) for move in legalStates ) ].sort( reverse = True )
Q2 : обратите внимание, что aFunc - это просто оболочка вокругbFunc 'потому что я не смог написать эквивалентное представление в вызове functools.partial( aFunc )
.
Какое выражение' aFunc 'в functools.partial( aFunc )
, которое я ищу, , которое позволит мне вызвать'bFunc' напрямую ?
РЕДАКТИРОВАТЬ : Ответ на вопрос 2: lambda ( v, m, s ): bFunc(s.something, 10)
Таким образом, утверждения становятся:
print "min( successorsSortedGen ) -> " + str( min( successorsSortedGenFn(), key=functools.partial( lambda ( v, m, s ): bFunc(s.something, 10)) ) )
print
print "max( successorsSortedGen ) -> " + str( max( successorsSortedGenFn(), key=functools.partial( lambda ( v, m, s ): bFunc(s.something, 10)) ) )
Я знаю, что-то вродекажется хромым, я не думал об этом раньше, ну да ладно (спасибо aaronasterling за мягкое подталкивание).
Q3, Q4 : Обратите внимание, что элементы перешли в min () и max () уже отсортированы.
Могу ли я сделать эту подсказку для min () и max (), чтобы он не создавал весь список как временный, а затем перебирал весьсписок для поиска элемента min или max?
Если нет, существует ли модуль или пользовательская функция, которая не создает экземпляр всего списка, но, учитывая, что список, переданный ему, отсортирован, возвращает minили максимальный элемент при проверке наименьшего количества элементов ?