Limitar добавляют довод "против" un número n de iteraciones para operar listas fuera y dentro de una clase

Tengo un código que tiene una estructura, подобный а-ля siguiente, en pseudocódigo. En el ejemplo en pseudocódigo se ха escrito class Uno y def main() para dar una idea de la estructura общий del código реальный que utilizo e intentar transmitir la idea de que habrá asignación de valores de dentro afuera de la clase y наоборот. Он decidido esta aproximación intentando plantear un ejemplo mínimo que sea а-ля vez mínimamente когерентный para el propósito de la pregunta.

from numpy import mean
x = []
nueva_x = [1,1]
class Uno: 
    mi_lista=[[1,1],[1,1],[0,1],[0,1],[0,0],[1,0]]
    for i in mi_lista:
         x.append(i)
    print(nueva_x)
def main():
    variable_1 = [1,2,3]

Es decir, declaro inicialmente una variable x que es una lista vacía y una variable nueva_x, que es una lista que contiene inicialmente una serie de valores. La Листа x va adjuntando sucesivamente las listas que hay dentro de mi_lista.

Lo que busco es:

  1. que la lista x vaya adjuntando las listas de mi_lista por el mismo número de iteraciones que elementos tiene variable_1 (en el ejemplo 3).

  2. una vez se hayan adjuntado en x un número de listas igual a len(variable_1), y sólo entonces, относящиеся к исчислению la медиа de los доблесть de las listas Адхунтас en x y asignarlo a nueva_x. En el ejemplo, una vez x ха adjuntado 3 listas x=[[1,1],[1,1],[0,1]], calculamos la media así media_x=mean(x, 0).

Реальный El objetivo es que cuando corra el código, el nueva_x том dentro de la clase el доблесть inicial имеет к que se cumplan las "n" primeras iteraciones (en el ejemplo 3). Desde entonces nueva_x tomará su nuevo доблесть, y así имеет к que se cumpla nuevamente el criterio del paso 1. Y así sucesivamente.

Mis intentos имеет к ahor ханьскому удару рапирой por farragosas funciones. Сенсилла Pero estoy seguro que tiene que existir una manera de ограничитель el número de listas que se adjuntan подставляет alguna función подобный a append. Una vez, hecho esto, меня gustaría сабля cómo proceder подставляет el Тему доблесть de la sustitución y asignación del nuevo a new_x, así Комо cómo formatear la lista x.

Gracias por los comentarios de antemano.

Actualización подставляют ООН código реальный (6/11/2019)

continuación vemos ООН ejemplo подставляет реальный un código más aproximado al código. Se trata de un ejemplo mínimo del código, реальный (abajo comparto el código).

Contexto:

Como puede observarse al ejecutarse el simulador, el juego (juego.jugar) Итера lo ларго de ronda en los emparejamientos. De este modo, cuando la ejecución llega al punto clave def choose, se imprime el self.sigma correspondiente al jugador (tomado de self.nombre) напоминание que está siendo simulado en ese. Комо puede observarse self.sigma доблесть довода "против" es una lista de 0 1.

Objetivo

Se desea crear una variable i que vaya adjuntando las listas self.sigma de cada "jugador" por el mismo número de iteraciones que jugadores tenemos. Существующий En el caso, 4.

Una vez se haya adjuntado en i un número de listas igual a len(jugadores), y sólo entonces, относящиеся к исчислению la медиа de los доблесть de las listas Адхунтас en i y asignarlo a nueva_i. En el ejemplo, una vez i ха adjuntado 4 listas i=[[1,1,0,0],[1,1,0,0],[0,0,1,1],[0,0,1,1]], calculamos la media así media_i=mean(i, 0).

Dado que la media de i en cada Ронда, es decir nueva_i, симулируйте сер utilizada en el futuro para hacer una serie de cálculos lo ларго de la simulación dentro de def choose, esta Листа nueva_i подросток debe asignado доблесть ООН previo cada Ронда (su доблесть iniciar será el de las medias de las sigmas iniciales asignadas en main()). su vez, en una futura versión del código, dentro de def_choose, esta nueva_i interferirá en cada Ронда подставляет el self.sigma de cada jugador, modificándolo. En resumen, se necesita que nueva_i recoja la media de self.sigmas de la предшествующая Ронда. Cada jugador tendrá su self.sigma propio, pero nueva_i será común todos los jugadores en cada Ронда. Todas estas устраивается concatenadas explican ми, intento inicial de trabajar подставляет una глобальную переменную i фаза a que nueva_i медиа la de las self.sigma de los jugadores y luego se formatee de ronda en ronda.

from __future__ import division
from random import random
from bisect import bisect
from collections import deque, Counter

i=[]
nueva_i=[]    

def choice(opciones, probs):
    probAcumuladas = list()
    aux = 0
    for p in probs:
        aux += p
        probAcumuladas.append(aux)
    r = random() * probAcumuladas[-1]
    op = bisect(probAcumuladas, r)
    return opciones[op]

class Jugador:
    def __init__(self, nombre, senales, sigma, b, x, m, menLen):
        self.nombre = nombre
        self.senales = senales
        self.mem_mostradas = {senal: 0 for senal in senales}
        self.men_observadas = {senal: 0 for senal in senales}
        self.__mem_mostradas = deque(maxlen=menLen)
        self.__men_observadas = deque(maxlen=menLen)
        self.sigma = sigma[:]  
        self.b = b
        self.x = x
        self.m = m

    def memoriza(self, mostrada, observada):
        self.__mem_mostradas.append(mostrada)
        self.__men_observadas.append(observada)
        mostradas = Counter(self.__mem_mostradas)
        observadas = Counter(self.__men_observadas)
        self.mem_mostradas = { signal: mostradas.get(signal, 0) for signal in self.senales }
        self.mem_observadas = { signal: observadas.get(signal, 0) for signal in self.senales }

    def __str__(self):
        return "Jugador_{}".format(self.nombre)

    def with_b(self, muestra, observa, r, idx):
        if not (muestra == observa == 0):
            result = (
                ((0.98) * (1.0 - self.b) * (1.0 - self.x) * muestra / r)
                + ((0.98) * (1.0 - self.b) * (self.x) * observa / r)
                + ((0.98) * self.b * self.sigma[idx])
                + ((self.m / 8))
            )
        else:
            result = (
                ((0.98) * (1.0 - 0) * (1.0 - self.x) * muestra / r)
                + ((0.98) * (1.0 - 0) * (self.x) * observa / r)
                + ((0.98) * 0 * self.sigma[idx])
                + ((self.m / 8))
            )
        return result

    def choose(self, r):
        probs = [
            self.with_b(
                self.mem_mostradas[op], self.men_observadas[op], r, indx
            )
            for indx, op in enumerate(self.senales)
        ]
        elecc = choice(self.senales, probs)

        #Aquí es donde se necesitará llamar a self.sigma y nueva_i
        print(self.sigma)
        print(nueva_i)

        return elecc

class Partida:
    def __init__(self, jugadores, emparejamientos, senales, sigmas, b, x, m, menLen):
        self.emparejamientos = emparejamientos
        self.senales = senales
        self.jugadores = {
            nombre: Jugador(nombre, senales, sigmas[nombre], b, x, m, menLen)
            for nombre in jugadores
        }
        self.memoria = list()
        self.entropy = float()

    def generar_senales(self):
        yield dict(zip(self.jugadores, self.senales))
        r = 1
        while True:
            eleccs = {}
            for jugador in self.jugadores.values():
                eleccs[jugador.nombre] = jugador.choose(r)
            r += 1
            yield eleccs

    def jugar(self):
        gen_sens = self.generar_senales()
        for ronda in self.emparejamientos:
            senales = next(gen_sens)
            self.memoria.append(senales)
            for jugador1, jugador2 in ronda:
                self.jugadores[jugador1].memoriza(observada=senales[jugador2], mostrada=senales[jugador1])
                self.jugadores[jugador2].memoriza(observada=senales[jugador1], mostrada=senales[jugador2])

def main():
    jugadores = [1, 2, 3, 4]
    senales = ["S1", "S2", "S3", "S4"]
    emparejamientos = [[(1, 2), (3, 4)], [(1, 3), (2, 4)], [(1, 4), (2, 3)]]

    patron = 1

    menLen=3

    s1 = [1, 0, 0, 0]
    s2 = [0, 0, 0, 1]
    sigmas = {1: s1, 2: s1, 3: s2, 4: s2}

    muestras = [{"b": 0.0, "x": 0.5, "m": 0.02}]

    muestras = [d for d in muestras for _ in range(1)]

    simulaciones = 1

    for sim in range(simulaciones):
        for mu in range(len(muestras)):
            juego = Partida(
                jugadores,
                emparejamientos,
                senales,
                sigmas,
                muestras[mu]["b"],
                muestras[mu]["x"],
                muestras[mu]["m"],
                menLen
            )
            juego.jugar()

if __name__ == "__main__":
    main()
4
задан 10.11.2019, 14:56
1 ответ

Проблема

Я Думаю, что в фоне говорится о проблеме XY, а именно, у пользователя есть необходимость X, но спроси из-за другой вещи Y, (так как попробовав решать X он apareciГі проблема Y). Этот тип вопросов они обычно занимают много времени, и много переливание сообщений, до в конце концов проясняют cuГЎl, было X и cuГЎl Y. Вслед за несколькими комментариями, переизданиями вопроса, и т.д. я прибыл к следующей conclusiГіn

Проблема X, что пользователь оригинально tenГ - в serГ - в:

Для каждого ночного обхода игры, я хочу вычислить среднюю величину списков, хранившихся в объектах - игроках, так что эти объекты могут использовать потом эту informaciГіn в следующем ночном обходе.

, Но пойдя осуществлять эту идею, пользователь encontrГі с проблемами видимости переменных. Список игроков estГЎ в месте. Она informaciГіn "sigma" (которые являются стоимостью, средняя величина которой хочет считать) estГЎn в другом месте, внутри каждого игрока. И она funciГіn, в которой pretendГ, - чтобы осуществлять среднюю величину estarГ - в aГєn в другом месте (одна funciГіn глобальный), с которым не sabГ - в cГіmo соглашаться на данные игроков, и т.д. AdemГЎs, так как игроки despuГ©s нуждались в том, чтобы согласиться в результате этой средней величины, decidiГі сделать эту среднюю величину глобальная переменная.

Перед этой сценой, не знал, как продолжаться, и planteГі вопрос Y, что vendrГ - чтобы в быть:

CГіmo соглашаться на списки внутри и вне класса одновременно, который ограничивается nГєmero повторений basГЎndose в контентах другого списка.

Восток проблема Y много mГЎs difГ-cil понимания и решения, и поэтому вопрос был время, не получая ее atenciГіn.

, Но сейчас, когда проблема X estГЎ просвет, мы произошли в Ваш soluciГіn.

SoluciГіn

Использование глобальных переменных разубеждается. Совсем informaciГіn, в котором одна funciГіn нуждалась, должен проходить с ним как parГЎmetro. Если мы используем programaciГіn ориентируемая объекты, мы можем упрощать немного, так как в этом случае функции - mГ©todos объекта и они могут соглашаться (vГ - в self) на признаки объекта, что vendrГ-an, чтобы быть глобальными переменными, но especГ-ficas этого объекта.

Используя эту идею я предлагаю:

  • , Который cГЎlculo nuevas_i, список со средними величинами, был бы сделан с одного mГ©todo из класса Partida, так как у этого класса есть в одном из Ваших признаков список игроков, что он permitirГЎ повторять из-за этого списка и соглашаться на sigma каждого игрока, без большей проблемы.
  • , Что вытекающая стоимость из nuevas_i сохраняла как признак класса Partida, так как она готова, - Гєtil для всех игроков (algГєn способ она compartirГЎn все).
  • , Что она funciГіn choose, которые нуждаются в этом списке, получил ее как parГЎmetro. В этом случае не моги брать ее из объекта Partida, потому что она funciГіn choose принадлежит каждому игроку.

С этими идеями изменения в cГіdigo serГ-an:

  • Удалять глобальные переменные i и nueva_i (и помещать один import numpy as np для последующего cГЎlculo средней величины)
  • Изменять choose() для того, чтобы он получил один parГЎmetro добавочный: nueva_i
  • Изменять строитель Partida.__init__() для того, чтобы он инициализировал self.nueva_i со средней величиной начальных sigmas:

        self.nueva_i = np.mean(list(sigmas.values()), 0)
    
  • Изменять призыв к choose(), чтобы перемещать его self.nueva_i, в mГ©todo Partida.generar_senales(). Они lГ-neas в cuestiГіn quedarГ-an asГ-:

            for jugador in self.jugadores.values():
                eleccs[jugador.nombre] = jugador.choose(r, self.nueva_i)
    
  • Изменять mГ©todo Partida.jugar() для того, чтобы он был в конце каждого ночного обхода, когда обновят self.nueva_i со средней величиной в cuestiГіn. Новость versiГіn этого mГ©todo остается asГ-:

    def jugar(self):
        gen_sens = self.generar_senales()
        for ronda in self.emparejamientos:
            senales = next(gen_sens)
            self.memoria.append(senales)
            for jugador1, jugador2 in ronda:
                self.jugadores[jugador1].memoriza(observada=senales[jugador2], mostrada=senales[jugador1])
                self.jugadores[jugador2].memoriza(observada=senales[jugador1], mostrada=senales[jugador2])
            # Calcular la media de las sigmas de la ronda anterior
            i = [ jugador.sigma for jugador in self.jugadores.values() ]
            self.nueva_i = np.mean(i, 0)
    

ВЎY я думаю, что это совсем! Я остаюсь в ожидании добавочных комментариев, чтобы видеть, если habГ - во включенное добро проблема X (проблема Y почти, что уже отказался :-))

4
ответ дан 01.12.2019, 12:21
  • 1
    Действительно, мой начальный подход состоял в том, чтобы делать переменные i и nueva_i глобальных, чтобы потом мочь соглашаться на них с def_choose. Ввиду того, что i и nueva_i стремятся к тому, чтобы быть теми же самыми для каждого игрока в каждом ночном обходе, Partida podrí в одно хорошее место, чтобы это осуществлять. Я достиг чего-то похожего посредством implementació n i и nueva_i глобальные, хотя кажется, что это не способ má s подходящий того, чтобы переходить. – pyring 10.11.2019, 12:48
  • 2
    С другой стороны, interpretació n покажись правильной, пока. Я существую añ adido má s informació n в начальном вопросе, чтобы пробовать saisfacer, ты сомневаешься. Большое спасибо @abufalia – pyring 10.11.2019, 13:25
  • 3
    Для того, чтобы я закончил узнавать и смог предлагать solució n. У каждого игрока есть один choose(), с которого нужно использовать nueva_i (но не i, правда?) я понимаю, что má s простой serí чтобы перемещать его этот список как pará метр в choose(). С другой стороны, ¿ dó nde construirí в nueva_i? Я предложил в mé совсем Разделенный класс, но ¿ qué mé весь serí в? ¿ с dó nde он так называемый? – abulafia 10.11.2019, 14:43
  • 4
    Действительно, у каждого игрока есть один choose(), с которого нужно использовать nueva_i, но не i. Список i ideé как глобальный список просто инструментальная для obetener nueva_i, но не operará с нею (не interferirá в simulació n). С другой стороны, я habí в вознамерившийся строить nueva_i из глобального способа. Однако, очень возможно это не было рекомендуемым. Quizá было лучше делать это внутри Partida. Я существую añ adido комментарий в có я говорю точно в месте, где имеется намерение использовать столько sel.sigma как nueva_i. – pyring 10.11.2019, 15:03
  • 5
    @abufalia Большое спасибо из-за solució n, что, поскольку это обычно, превосходный и оно обозначает необыкновенную способность понимать выдвинутые проблемы и давать им ответ didá ctica. Действительно, эта solució n много má s элегантный и эффективный, что та глобальной переменной, что sugerí в. Я нуждаюсь в том, чтобы сделать пару проверок má s mañ ана, чтобы видеть, отвечает ли все на то, что я точно ищу в притворном. Между тем, если ты считаешь, что tí tulo вопроса смоги быть изданным, чтобы подбирать лучше отнесенную тему, я весь oí два. – pyring 11.11.2019, 01:56

Теги

Похожие вопросы