Pregunta

Considere el siguiente código, integrante a mis preguntas a continuación:

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

Mis preguntas se basan en las declaraciones marcadas como "#Q":

Q1 : Es evidente que el generador se crea una instancia por completo (todos los elementos son ejecutados), como lo llamamos sorted() en él (que genera todos los elementos y crea una lista sin ordenar temporal que ordena y vuelve como una nueva lista?).

¿Hay una manera eficiente el espacio, que reduce al mínimo la creación de provisionales y yeilds una ordenada lista?

Lo intenté, pero no podría escribir una lista por comprensión que podría ordenar en su lugar usando list.sort()

Este fue el tipo de expresión que estaba pensando en:

successorsSorted = [ ( s.something, m, s ) for ( m, s ) in ( ( move, doit( move ) ) for move in legalStates ) ].sort( reverse = True )

Q2 . Tenga en cuenta que 'aFunc' es sólo una envoltura alrededor 'bFunc' porque no era capaz de escribir una representación equivalente en la llamada functools.partial( aFunc )

¿Cuál es la expresión 'aFunc' en functools.partial( aFunc ) que Busco que permitirá que la llame 'bFunc' directamente


Editar : La respuesta a la Q2 es lambda ( v, m, s ): bFunc(s.something, 10)

Por lo tanto, las declaraciones se convierten en:

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)) ) )

Sé que parece un poco cojo yo no pensé en esto antes, pero bueno (gracias a aaronasterling para la punzada suave).


Q3, Q4 :. Obsérvese que los elementos pasados ??a min () y max () ya están ordenados

¿Es posible para mí hacer esta receta a min () y MAX () para que no crear una instancia de toda la lista como temporal y luego iterar a través de toda la lista para localizar el elemento de mínimos y máximos?

Si no, ¿hay una función de módulo o la costumbre en la existencia que no crear una instancia de toda la lista, pero, dado que la lista que se le pasa se clasifica, se devuelve el min o elemento max al inspeccionar el menor número de elementos

¿Fue útil?

Solución

Q1. [x for x in somelist].sort() crea una lista y llama al método sort. Esto devuelve None Los cesionarios de asignación None a successorSorted. Si quieres hacer esto, usted tiene que aplicar por sí mismo y es probable que sea manera más lenta que la orden interna creando una especie de la lista temporal.

Q2. Se podía desarmar el objeto de código y reorganizar la lista de argumentos de manera que a es el primer argumento y luego volver a escribir todo el código de bytes para dar cuenta de las nuevas posiciones de los locales. (Sí en realidad esto puede hacerse). A continuación, puede utilizar functools.partial en eso. O puede utilizar un envoltorio que estás haciendo ahora o en algunas otras maneras. Soy 1 en el envoltorio. (A pesar de que me haga saber si desea un corte de código de bytes, creo que son la diversión y el fresco cosa acerca de ellos como proporcionar respuestas sobre desbordamiento de pila es que tengo que escribirlas, pero no tienen en su uso;)

Q3, Q4. Realmente no. Para obtener el elemento de la décima parte de un iterador, tiene que pasar por todos los anteriores. Si sabe que desea que el primer elemento, sólo puede hacerlo

smallest = next(sorted_iterator)

y para la última

for item in iterable: pass
largest = item

La primera va a comer el primer elemento del repetidor y el último va a comer todo el iterador. Bye Bye iterador.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top