Clinton Moffat
Clinton Moffat

Reputation: 211

Python loop efficiency

I was just wondering if there is a more cpu efficient way of writing the following loop as I need to speed my program up?

for char in data:
    if char in self.key:
        match += chr(self.key.index(char))

Thanks in advance for any help.

Upvotes: 4

Views: 1651

Answers (3)

Viktor Kerkez
Viktor Kerkez

Reputation: 46636

Yes, use a dictionary instead of a list. index operation is slow (it's O(log(N)) as is the check if the element is in the list, while dictionary access is O(1))

self.map = dict(zip(self.key, range(len(self.key)))
for char in data:
     if char in self.map:
        match += chr(self.map[char])

Also change the constant adding to the string to just one string concatenation using join and a generator expression inside (avoid list creation):

result = ''.join(chr(self.map[char]) for char in data if char in self.map)

Upvotes: 4

Martijn Pieters
Martijn Pieters

Reputation: 1125268

Replace self.key with a dictionary; it is the membership testing against a list, as well as the .index() calls that are costing you the most performance; both require scans across the list.

Use str.join() to concatenate a series of characters; that builds one new string object instead of N new objects:

keys = {char: chr(i) for i, char in enumerate(self.key)}
match = ''.join([keys[char] for char in data if char in keys])

Dictionary membership tests and lookups are O(1) constant cost; by building the dictionary with char(..) values you can avoid multiple chr() calls per value; depending on how many values are re-used it could be faster to use char: i instead and move the chr() call to the list comprehension.

Upvotes: 7

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 799560

match = ''.join(char for char in data if char in self.key)

Upvotes: 3

Related Questions