2016-04-15 2 views
2

Ich führe ein Python-Skript, das zwei riesige Listen iteriert und die passenden Paare findet.Wie beschleunigt man das Python-Skript, das die verschachtelte Schleife iteriert?

Es scheint jedoch ewig zu dauern. Wie beschleunigt man dieses Skript?

import sys 
import random 
import itertools 

def main(args): 
    target_num = int(999999999) 
    num_list = range(1, target_num) 
    rand_list = [] 
    hit_list = [] 

    for _ in itertools.repeat(None, target_num): 
     rand_list.append(random.randint(1, target_num)) 

    for num in num_list: 
     for rand_num in rand_list: 
      if num == rand_num: 
       print "hit" 

if __name__ == "__main__": 
    main(sys.argv[1:]) 
+1

Versuchen Sie nicht, integrierte Namen als Variablennamen in Ihrem Code zu verwenden, da dies zu Frustration führen kann. Damit meine ich die Verwendung von 'list' als Variablennamen – smac89

+0

@ Smac89 Ich hatte es eilig, eine Frage zu schreiben, und machte einen Fehler. Ich habe den Variablennamen geändert. – Han

+0

Soll diese zweite verschachtelte Schleife 'read_list' oder' rand_list' sein? – smac89

Antwort

3

Verwenden

import sys 
import random 
import itertools 

def main(args): 
    target_num = int(999999999) 
    num_list = set(range(1, target_num)) 
    rand_list = [] 
    hit_list = [] 

    for _ in itertools.repeat(None, target_num): 
     rand_list.append(random.randint(1, target_num)) 


    for num in rand_list: 
     if num in num_list: # O(1) 
      print "hit" 

if __name__ == "__main__": 
    main(sys.argv[1:]) 

Unter Verwendung eines Satzes für die erste Liste enthält, bedeutet, dass geprüft wird, ob das Element in dieser Liste ist jetzt auf einen O reduziert wird (1)


Während ich dies schreibe, merke ich, dass du es sogar besser machen kannst. Die range Funktion in Python 3 gibt eine Sequenz, so müssen Sie Python 3 für diesen nächsten Teil besser

import sys 
import random 
import itertools 

def main(args): 
    target_num = int(999999999) 
    num_list = range(1, target_num) # this is a generator 
    rand_list = [] 
    hit_list = [] 

    for _ in itertools.repeat(None, target_num): 
     rand_list.append(random.randint(1, target_num)) 


    for num in rand_list: 
     if num in num_list: # Stil O(1) 
      print ("hit") 

if __name__ == "__main__": 
    main(sys.argv[1:]) 

Selbst, Bereich verwenden und die Kontrolle innerhalb der ersten Schleife zu tun?

+0

'O (1)' Mitgliedschaft Tests ist keine Funktion von 'xrange', es wurde nur hinzugefügt, um' range' in [Python 3.2, wenn sie schließlich die Implementierung der Sequenz ABC für 'range' abgeschlossen] (https: // docs. python.org/3/library/stdtypes.html#range). 'xrange'-Membership-Tests generieren und testen Werte einzeln, bis ein Treffer erzielt wird. Auch sind weder "Range" noch "Xrange" Generatoren; sie sind mehr oder weniger Sequenzobjekte, die Iteratoren erzeugen können, nicht Iteratoren/Generatoren selbst; Wenn sie Generatoren wären, würden sie sie einmal erschöpfen, aber so verhalten sie sich nicht. – ShadowRanger

+0

@ShadowRanger Yup du hast Recht – smac89

1

Wenn Sie Python 2 verwenden, verwenden Sie xrange(), das ein generatorähnliches Objekt zurückgibt.

# requires Python 2 
import random 

target_num = 99 # 999999999 are too much items for testing 

# target_num random numbers in range 1 .. target_num-1 
random_numbers = set(random.randint(1, target_num) for _ in xrange(target_num)) 

hits = set() 
for num in xrange(1, target_num): # check for all numbers in range 1 .. target_num-1 
    if num in random_numbers: # num in set() is O(1) 
     hits.add(num) 

if len(random_numbers - hits) == 0: 
    print "all random numbers are hits!" 

# so: 
for num in random_numbers: 
    print num 
# is the same result