2010-01-19 32 views
5

Đây là câu hỏi về giá trị tương đối của mã nhanh sử dụng thư viện chuẩn nhưng ít được biết đến (ít nhất là đối với tôi) so với thay thế bằng tay. Trong thread (và những thứ khác mà nó trùng lặp), có vẻ như cách "Pythonic" để chia danh sách thành các nhóm là sử dụng itertools, như trong hàm đầu tiên trong ví dụ mã bên dưới (được sửa đổi nhẹ từ ΤΖΩΤΖΙΟΥ). Lý do tôi thích chức năng thứ hai là tôi có thể hiểu nó hoạt động như thế nào, và nếu tôi không cần đệm (chuyển chuỗi DNA thành codon), tôi có thể tái tạo nó từ bộ nhớ ngay tức thì.Python: đối số để sử dụng itertools để chia danh sách thành các nhóm

Tốc độ tốt hơn với công cụ lặp. Đặc biệt nếu chúng ta không muốn một danh sách trở lại, hoặc chúng ta muốn pad mục nhập cuối cùng, thì itertools sẽ nhanh hơn.

Các đối số khác có lợi cho giải pháp thư viện chuẩn nào?

from itertools import izip_longest 

def groupby_itertools(iterable, n=3, padvalue='x'): 
    "groupby_itertools('abcde', 3, 'x') --> ('a','b','c'), ('d','e','x')" 
    return izip_longest(*[iter(iterable)]*n, fillvalue=padvalue) 

def groupby_my(L, n=3, pad=None): 
    "groupby_my(list('abcde'), n=3, pad='x') --> [['a','b','c'], ['d','e','x']]" 
    R = xrange(0,len(L),n) 
    rL = [L[i:i+n] for i in R] 
    if pad: 
     last = rL[-1] 
     x = n - len(last) 
     if isinstance(last,list): 
      rL[-1].extend([pad] * x) 
     elif isinstance(last,str): 
      rL[-1] += pad * x 
    return rL 

thời gian:

$ python -mtimeit -s 'from groups import groupby_my, groupby_itertools; L = list("abcdefghijk")' 'groupby_my(L)' 
100000 loops, best of 3: 2.39 usec per loop 

$ python -mtimeit -s 'from groups import groupby_my, groupby_itertools; L = list("abcdefghijk")' 'groupby_my(L[:-1],pad="x")' 
100000 loops, best of 3: 4.67 usec per loop 

$ python -mtimeit -s 'from groups import groupby_my, groupby_itertools; L = list("abcdefghijk")' 'groupby_itertools(L)' 
1000000 loops, best of 3: 1.46 usec per loop 

$ python -mtimeit -s 'from groups import groupby_my, groupby_itertools; L = list("abcdefghijk")' 'list(groupby_itertools(L))' 
100000 loops, best of 3: 3.99 usec per loop 

Edit: Tôi sẽ thay đổi tên hàm ở đây (xem câu trả lời của Alex), nhưng có rất nhiều, tôi quyết định gửi cảnh báo này để thay thế.

+1

Tôi đã nhận được câu trả lời tôi mong đợi, tôi đoán vậy. Cảm ơn. Sẽ dễ nuốt hơn (như mẹ bảo tôi ăn rau bina của tôi), nếu tôi có thể nhìn vào * [iter (iterable)] * n và hiểu nó làm gì. Tuy nhiên, cho rằng một docstring luôn luôn là một ý tưởng tốt, tôi cho rằng việc sử dụng các itertools được ghi nhận đủ tốt trong mã. Và tôi chắc chắn đánh giá cao công việc của chuyên gia đã đi vào thư viện chuẩn. – telliott99

Trả lời

15

Khi bạn sử dụng lại các công cụ từ thư viện chuẩn, thay vì "phát minh lại bánh xe" bằng cách tự viết mã từ đầu, bạn không chỉ nhận được phần mềm được tối ưu hóa và điều chỉnh tốt (đôi khi đáng kinh ngạc như vậy) itertools thành phần): quan trọng hơn, bạn đang nhận được một lượng lớn chức năng mà bạn không phải kiểm tra, gỡ lỗi và duy trì bản thân - bạn đang tận dụng tất cả các công việc kiểm tra, gỡ lỗi và bảo trì của nhiều lập trình viên tuyệt vời, những người đóng góp cho thư viện chuẩn!

Việc đầu tư vào việc hiểu thư viện chuẩn cung cấp gì cho bạn, do đó bạn có thể tự hoàn trả nhanh và nhiều lần - và bạn sẽ có thể "tái tạo từ bộ nhớ" cũng như mã được phát minh lại. nhờ vào lượng tái sử dụng cao hơn. Bằng cách này, thuật ngữ "nhóm theo" có ý nghĩa thành ngữ, rõ ràng cho hầu hết các lập trình viên, nhờ sử dụng trong SQL (và cách sử dụng tương tự trong chính bản thân mình): Tôi sẽ khuyên bạn nên tránh sử dụng nó cho một điều gì đó hoàn toàn khác - điều đó sẽ gây nhầm lẫn bất cứ khi nào bạn cộng tác với bất kỳ ai khác (hy vọng thường xuyên, kể từ thời hoàng kim), lập trình viên "cao bồi" đã biến mất - một lý lẽ khác ủng hộ tiêu chuẩn và chống lại sự tái tạo bánh xe ;-).

Cuối cùng, chuỗi tài liệu của bạn không khớp với chữ ký của hàm của bạn - lỗi thứ tự đối số ;-).

+0

+1 Ngoài ra, ngay cả những người thực sự mã hóa một cái gì đó có thể bị nhầm lẫn khi họ nhìn vào nó một năm kể từ bây giờ. – balpha

+0

Cảm ơn, Alex.Trên thực tế, "của tôi" chức năng là một trong những không có docstring :) Tôi sẽ sửa chữa khác. – telliott99

5

Thời gian dành cho việc học các nguyên tắc cơ bản của Python sẽ được đền bù sau nhiều lần. Do đó, hãy tìm hiểu về công cụ lặp và cách hoạt động của nhóm. Không chỉ sử dụng các công cụ lặp có khả năng nhanh hơn bất kỳ giải pháp nào được quay bằng tay, nó sẽ giúp bạn viết mã tốt hơn trong tương lai.

Các vấn đề liên quan