以下の私の質問に不可欠な次のコードを検討してください。
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」とマークされたステートメントに基づいています。
Q1sorted()
:ジェネレーターを呼び出すと(すべての要素が生成され、ソートされて新しいリストとして返される一時的なソートされていないリストが作成されます)、ジェネレーターが完全にインスタンス化されている(すべての要素が実行されている)ことは明らかです。
一時的なものの作成を最小限に抑え、ソートされたリストを生成する、スペース効率の良い方法はありますか?
しようとしましたが、を使用して適切に並べ替えることができるリスト内包表記を記述できませんでした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 )
。
「bFunc」を直接呼び出すことができる表現「aFunc」とは何functools.partial( aFunc )
ですか?
編集:Q2への答えは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)) ) )
私はそれがちょっと足りないように見えることを知っています、私はこれについて以前は考えていませんでしたが、まあ(穏やかなproddingのためのaaronasterlingのおかげで)。
Q3、Q4:min()とmax()に渡される要素はすでにソートされていることに注意してください。
このヒントをmin()とmax()に作成して、リスト全体を一時的なものとしてインスタンス化してから、リスト全体を反復処理してminまたはmax要素を見つけないようにすることはできますか?
そうでない場合、リスト全体をインスタンス化しないモジュールまたはカスタム関数が存在しますが、渡されたリストがソートされている場合、最小数の要素を検査しながら最小要素または最大要素を返しますか?