2010-07-01 45 views
9

Trong Lisp, bạn có thể có một cái gì đó như thế này:Lặp lại một chuỗi định dạng trên một danh sách

(setf my-stuff '(1 2 "Foo" 34 42 "Ni" 12 14 "Blue")) 
(format t "~{~d ~r ~s~%~}" my-stuff) 

Điều gì sẽ là cách Pythonic nhất để lặp qua đó cùng một danh sách? Điều đầu tiên bạn nghĩ đến là:

mystuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"] 
for x in xrange(0, len(mystuff)-1, 3): 
    print "%d %d %s" % tuple(mystuff[x:x+3]) 

Nhưng điều đó chỉ cảm thấy khó xử với tôi. Tôi chắc chắn có một cách tốt hơn?


Vâng, trừ khi ai đó sau cung cấp một ví dụ tốt hơn, tôi nghĩ rằng giải pháp gnibbler là đẹp nhất \ gần nhất, mặc dù nó có thể không khá rõ ràng lúc đầu như thế nào nó làm những gì nó làm:

mystuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"] 
for x in zip(*[iter(mystuff)]*3): 
    print "{0} {1} {2}".format(*x) 
+1

Là một sang một bên, không phải là khó xử như một từ tuyệt vời khủng khiếp? Nó chỉ * trông * vụng về! –

+2

Có vẻ khó xử khi so sánh nhưng nó thực sự không phải là xấu. – ChaosPandion

+2

+1 vì tôi không có đầu mối nếu bạn đang đề cập đến nhận xét hoặc mã của tôi. * Xin vui lòng * không làm rõ, sự mơ hồ là thú vị hơn nhiều/thú vị! –

Trả lời

11
mystuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"] 
for x in zip(*[iter(mystuff)]*3): 
    print "%d %d %s"%x 

Hoặc sử dụng .format

mystuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"] 
for x in zip(*[iter(mystuff)]*3): 
    print "{0} {1} {2}".format(*x) 

Nếu chuỗi định dạng không hardcoded, bạn có thể phân tích nó để tìm ra bao nhiêu thuật ngữ trên mỗi dòng

from string import Formatter 
num_terms = sum(1 for x in Formatter().parse("{0} {1} {2}")) 

Đặt tất cả lại với nhau cho

mystuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"] 
fmt = "{0} {1} {2}" 
num_terms = sum(1 for x in Formatter().parse(fmt)) 
for x in zip(*[iter(mystuff)]*num_terms): 
    print fmt.format(*x) 
+0

Tôi * thực sự * thích giải pháp này, và tôi đã thực sự bối rối lúc đầu nhưng sau khi hack vào mã thực sự thanh lịch. –

+0

@Wayne Werner, tốt về bạn để tìm ra lý do tại sao nó hoạt động –

3

Đối với người mới bắt đầu, tôi muốn sử dụng chuỗi mới hơn định dạng phương pháp trong 2.6+

print "{0} {1} {2}".format(*mystuff[x:x+3]) 
+0

Tôi đã quên mất điều đó. Làm sạch nó lên một chút ... –

4

tôi nghĩ join là tính năng tương tự như hầu hết các bằng Python:

(format t "~{~D, ~}" foo) 

print(foo.join(", ")) 

Đó là một chút tồi tệ hơn khi bạn có nhiều mục bên trong, như bạn thấy, tuy nhiên nếu bạn có một hàm group-by (đó là thực sự hữu ích anyway!), Tôi nghĩ bạn có thể làm cho nó làm việc mà không quá nhiều rắc rối. Một cái gì đó như:

mystuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"] 
print(["%d %d %s" % x for x in group(mystuff, 3)].join("\n")) 
+0

Có, với việc bổ sung một chức năng máy phát điện chuyên dụng, bạn có thể làm cho nó trông rất đẹp. –

+0

Vâng, tôi đoán nó phụ thuộc vào số tiền bạn muốn ăn gian. Bạn có thể chuyển 'FORMAT' sang Python và nói' FORMAT (True, "~ {~ d ~ r ~ s ~% ~}", my_stuff) ', nếu bạn thực sự chán một vài ngày cuối tuần. :-) – Ken

+0

Tôi đã bị cám dỗ! Tất nhiên tôi cũng muốn rằng '~ r' là một phần của thư viện Python, quá ... Đã có một mô-đun trên sourceforge: http: // sourceforge.net/projects/pynum2word/ –

2

tôi muốn nói nhất Pythonic sẽ làm cho danh sách sâu hơn:

mystuff = [(1, 2, "Foo"), (34, 42, "Ni"), (12, 14, "Blue")] 
for triplet in mystuff: 
    print "%d %d %s" % triplet 
+0

đó là cơ bản những gì giải pháp gnibblers tạo ra: '[x cho x trong zip (* [iter (mystuff)] * 3)]' = '[(1, 2, 'foo'), (34, 42, 'ni'), (12, 14, 'xanh')] 'Khá trơn, neh? –

+0

Tôi biết điều đó, nhưng tôi nghĩ rằng đó là nhiều Pythonic chỉ để có danh sách trong hình thức đó để bắt đầu. Đó là câu hỏi ban đầu, phải không? –

+0

Vâng, tôi hơi mơ hồ, vì vậy tôi đã cố định từ ngữ. Tôi thực sự quan tâm hơn đến việc lặp lại/định dạng một phần tiêu thụ một số giá trị danh sách nhất định cho mỗi lần lặp lại. Nhưng xét về toàn bộ "chương trình", giải pháp của bạn sẽ có nhiều pythonic hơn –

0

Một hai lót dựa trên Wright:

mystuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"] 
print '\n'.join("{0},{1},{2}".format(*mystuff[x:x+3]) for x in xrange(0, len(mystuff)-1, 3)) 
1
stuff = [1, 2, "Foo", 34, 42, "Ni", 12, 14, "Blue"] 

it = iter(stuff) 
itn = it.next 

print '\n'.join("%d %d %s" % (el,itn(),itn()) 
       for el in it) 

Rất dễ hiểu, tôi nghĩ

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