2011-08-16 25 views
28

tôi đang tạo ra tất cả các khả năng ba chữ từ khóa e.g. aaa, aab, aac.... zzy, zzz dưới đây là mã của tôi:Cách tốt nhất để tạo ra tất cả các chuỗi ba chữ cái có thể là gì?

alphabets = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'] 

keywords = [] 
for alpha1 in alphabets: 
    for alpha2 in alphabets: 
     for alpha3 in alphabets: 
      keywords.append(alpha1+alpha2+alpha3) 

chức năng này có thể đạt được trong một cách kiểu dáng đẹp và hiệu quả hơn?

Trả lời

68
keywords = itertools.product(alphabets, repeat = 3) 

Xem documentation for itertools.product. Nếu bạn cần một danh sách các chuỗi, chỉ cần sử dụng

keywords = [''.join(i) for i in itertools.product(alphabets, repeat = 3)] 

alphabets cũng không cần phải là một danh sách, nó chỉ có thể là một chuỗi, ví dụ:

from itertools import product 
from string import ascii_lowercase 
keywords = [''.join(i) for i in product(ascii_lowercase, repeat = 3)] 

sẽ làm việc nếu bạn chỉ muốn lowercase ascii letters.

+0

Nếu bạn muốn tạo từng kết hợp ký tự mà không chiếm nhiều bộ nhớ, bạn có thể thay đổi '['' .join (i) cho i trong sản phẩm (ascii_lowercase, repeat = 3)]' đến '('' .join (i) cho i trong sản phẩm (ascii_lowercase, repeat = 3))' và lặp qua từng cái trong một vòng lặp 'for-in' – DCIndieDev

13

Bạn cũng có thể sử dụng bản đồ thay vì hiểu danh sách (đây là một trong những trường hợp bản đồ vẫn nhanh hơn là so với LC)

>>> from itertools import product 
>>> from string import ascii_lowercase 
>>> keywords = map(''.join, product(ascii_lowercase, repeat=3)) 

Này biến thể của danh sách hiểu cũng nhanh hơn so với sử dụng ''.join

>>> keywords = [a+b+c for a,b,c in product(ascii_lowercase, repeat=3)] 
+2

Với' join' bạn không phải thay đổi nó nếu bạn thay đổi giá trị của 'lặp lại' - thêm một số cliche về tối ưu hóa sớm ở đây. – agf

3
from itertools import combinations_with_replacement 

alphabets = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'] 

for (a,b,c) in combinations_with_replacement(alphabets, 3): 
    print a+b+c 
+1

Điều này không thực sự giống nhau. Hãy thử với hai chữ cái - bạn nhận được 26 kết hợp với 'a' làm chữ cái đầu tiên, sau đó là 25 cho' b', v.v., chỉ thành 'zz' cho' z' làm chữ cái đầu tiên. Tức là, bạn không nhận được cả hai 'ab' và' ba', hoặc để sử dụng ví dụ trong OP, bạn không nhận được 'zzy', bởi vì bạn đã có' yzz'. – agf

+0

hmm, tôi hiểu. Cảm ơn bạn đã chỉ ra điều đó. – Asterisk

2
chars = range(ord('a'), ord('z')+1); 
print [chr(a) + chr(b) +chr(c) for a in chars for b in chars for c in chars] 
3

Bạn cũng có thể làm điều này mà không cần bất kỳ module bên ngoài bằng cách làm s imple tính toán.
PermutationIterator là những gì bạn đang tìm kiếm.

def permutation_atindex(_int, _set, length): 
    """ 
    Return the permutation at index '_int' for itemgetter '_set' 
    with length 'length'. 
    """ 
    items = [] 
    strLength = len(_set) 
    index = _int % strLength 
    items.append(_set[index]) 

    for n in xrange(1,length, 1): 
     _int //= strLength 
     index = _int % strLength 
     items.append(_set[index]) 

    return items 

class PermutationIterator: 
    """ 
    A class that can iterate over possible permuations 
    of the given 'iterable' and 'length' argument. 
    """ 

    def __init__(self, iterable, length): 
     self.length = length 
     self.current = 0 
     self.max = len(iterable) ** length 
     self.iterable = iterable 

    def __iter__(self): 
     return self 

    def __next__(self): 
     if self.current >= self.max: 
      raise StopIteration 

     try: 
      return permutation_atindex(self.current, self.iterable, self.length) 
     finally: 
      self.current += 1 

Cung cấp cho nó một đối tượng có thể lặp lại và số nguyên là độ dài đầu ra.

from string import ascii_lowercase 

for e in PermutationIterator(ascii_lowercase, 3): 
    print "".join(e) 

Điều này sẽ bắt đầu từ 'aaa' và kết thúc bằng 'zzz'.

-1
print([a+b+c for a in alphabets for b in alphabets for c in alphabets]) 
Các vấn đề liên quan