[Python-es] Iterar 2 veces sobre 1 lista y comparar sus objetos lo mas rapido
Andrey Antoukh
andsux en gmail.com
Lun Mayo 9 00:28:26 CEST 2011
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.
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"
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://mail.python.org/pipermail/python-es/attachments/20110509/76d5f859/attachment.html>
Más información sobre la lista de distribución Python-es