[Python-es] Iterar 2 veces sobre 1 lista y comparar sus objetos lo mas rapido
lopz
lowlifebob en gmail.com
Lun Mayo 9 04:02:58 CEST 2011
El día 8 de mayo de 2011 18:28, Andrey Antoukh <andsux en gmail.com> escribió:
> Hola.
hola
> No se si estoy en lo cierto, pero puede que te haga falta un itertools.tee()
> http://docs.python.org/library/itertools.html#itertools.tee
> Un ejemplo simple:
> a = [1,2,3,4,5,6]
> from itertools import tee
> first, second = tee(a, 2)
> while True:
> try:
> first_next = next(first)
> second_next = next(second)
> if first_next == second_next:
> print first_next, second_next
> except StopIteration:
> break
>
> Un saludo.
> Andrei.
Voy a probarlo, no conocía tee :O , toca leer, gracias :)
> El 9 de mayo de 2011 00:17, lopz <lowlifebob en gmail.com> escribió:
>>
>> Hola, estoy haciendo unas pequeñas pruebas en pygame
>>
>> tengo un diccionario de palabras con tus tags, cada palabra será una
>> bola y si alguna de las palabras tiene igual tag que otra
>> entonces se unirán con una línea, y así hasta iterar sobre toda el
>> diccionario
>> actualmente tengo esto y funciona bien
>>
>> #!/usr/bin/env python
>> # -*- coding: utf-8 -*-
>>
>> import pygame
>> import random
>>
>> class Neurons():#pygame.sprite.Sprite):
>> def __init__(self, x, y, color, key, tags):
>> self.x = x
>> self.y = y
>> self.color = color
>>
>> self.key = key
>> self.tags = tags
>>
>> def draw(self, surf):
>> pygame.draw.circle(surf, self.color, [self.x, self.y], 10)
>>
>> def pos(self):
>> return (self.x, self.y)
>>
>> def line(surf, start, end):
>> pygame.draw.line(surf, read, start, end, 1)
>>
>> words = {'uno': '1 2 3',
>> 'dos': '3 4 5',
>> 'tres': '5 6 7',
>> 'cuatro': '2 5 8',
>> 'cinco': '5 3 7',
>> 'seis': '7 6 3'}
>>
>> pygame.init()
>>
>> black = [0, 0, 0]
>> white = [255, 255, 255]
>> read = [255, 0, 0]
>>
>> # Set the height and width of the screen
>> size = [400, 400]
>> screen = pygame.display.set_mode(size)
>> pygame.display.set_caption("Net")
>>
>> neurons = []
>>
>> for word in words:
>> x = random.randrange(100, 400)
>> y = random.randrange(100, 400)
>> neuron = Neurons(x, y, white, word, words[word])
>> neurons.append(neuron)
>>
>> clock = pygame.time.Clock()
>>
>> def compare(tags1, tags2):
>> for i in tags1.split(' '):
>> for j in tags2.split(' '):
>> if (i == j):
>> return True
>> return False
>>
>> neurons2 = neurons[:]
>>
>> done = False
>> while not done:
>> for event in pygame.event.get(): # User did something
>> if event.type == pygame.QUIT:
>> done = True
>>
>> screen.fill(black)
>>
>> for i in range(len(neurons)):
>> neurons[i].draw(screen)
>> #neuron = neurons.pop()
>> #neuron = neurons[i]
>> #neurons.remove(neurons[i])
>> for j in range(len(neurons)):
>> if (i != j):
>> if compare(neurons[i].tags, neurons[j].tags):
>> #print neurons[i].tags, neurons[j].tags
>> #print neuron.tags
>> line(screen, neurons[i].pos(), neurons[j].pos())
>>
>>
>>
>> pygame.display.flip()
>> clock.tick(20)
>>
>> pygame.quit()
>>
>>
>>
>> Resulta que siempre hacía dos 2 anidados e iba comparando uno con
>> todos, pero ahora que me doy cuenta estoy gastando recursos
>> por que si una palabra y sus tags, por ej
>> bar: 1, 2, 3
>> y otra palabra
>> foo: 4, 2, 5
>> Resulta que tienen el tag 2 en común, y cuando se itera primero bar y
>> luego foo entonces se traza una línea entre palabras, pero cuando la
>> iteración
>> le toque a foo en el primer for y en el segundo a bar, tendrán la
>> mismo tag en común, entonces:
>> Se trazarían 2 líneas, una desde bar -> foo y otra de foo -> bar pero
>> como tienen los mismos puntos parece ser que es una sola línea.
>>
>> Entonces he decidio cojer un objeto y eliminarlo de la lista, con pop
>> e iterar de nuevo pero en el segundo for ya no habría ese objeto
>> entonces
>> me ahorraría ese if ( i != j) y además menos una iteración, la próxima
>> menos 2 y así hasta la mitad, de funcionar funciona
>> el problema está en que como todo tiene que repetirse con el while la
>> lista está vacía para el 2do while jeje hay alguna forma de quitar de
>> la lista un objeto pero sin eliminarlo?
>> de seguro que es fácil pero no me doy cuenta :(
>> He intentado con copiar a otra lista, pero en la 2da iteración del
>> while ya está vacía, además no es la idea copir otra lista si no
>> remover en el primer for el objeto
>> para que en el 2do ya no se itere y no tenga que comparar si es el
>> mismo y además será mucho más rápido
>>
>> gracias :)
>>
>> --
>> lopz es libre, usa --> GNU/linux gentoo
>>
>> +--[RSA 2048]--+
>> | ..o.o=+ |
>> | o =o*.+ |
>> | . . *oO . |
>> | .EBoo |
>> | o.S |
>> +--[lopz.org]--+
>> _______________________________________________
>> Python-es mailing list
>> Python-es en python.org
>> http://mail.python.org/mailman/listinfo/python-es
>> FAQ: http://python-es-faq.wikidot.com/
>
>
>
> --
> http://twitter.com/andsux
> http://www.niwi.be
> ****
> http://www.freebsd.org/
> http://www.postgresql.org/
> http://www.python.org/
> http://www.djangoproject.com/
>
> "Linux is for people who hate Windows, BSD is for people who love UNIX"
> "Social Engineer -> Because there is no patch for human stupidity"
>
> _______________________________________________
> Python-es mailing list
> Python-es en python.org
> http://mail.python.org/mailman/listinfo/python-es
> FAQ: http://python-es-faq.wikidot.com/
>
>
--
lopz es libre, usa --> GNU/linux gentoo
+--[RSA 2048]--+
| ..o.o=+ |
| o =o*.+ |
| . . *oO . |
| .EBoo |
| o.S |
+--[lopz.org]--+
Más información sobre la lista de distribución Python-es