2009-02-01 35 views
7

Dòng cuối cùng có ý nghĩa gì trong đoạn mã sau?Vấn đề trong việc hiểu sự hiểu biết danh sách Python

import pickle, urllib                                      

    handle = urllib.urlopen("http://www.pythonchallenge.com/pc/def/banner.p") 
    data = pickle.load(handle) 
    handle.close() 

    for elt in data: 
     print "".join([e[1] * e[0] for e in elt]) 

nỗ lực của tôi cho vấn đề:

  • "" .join ... sử dụng tham gia -method để văn bản trống
  • e [1] * e [0] sẽ nhân hai giá trị tiếp theo trong trình tự, e
  • tôi không chắc chắn e
  • tôi không chắc chắn, là những gì ý nghĩa của nó, khi bạn có một cái gì đó trước khi cho -loop, như: e[1] * e[0] for e in elt
+0

Tôi thực sự thích thử thách python khi tôi lấy nó một vài năm trước. –

Trả lời

19

Có lẽ giải thích tốt nhất với một ví dụ:

print "".join([e[1] * e[0] for e in elt]) 

là hình thức ngắn

x = [] 
for e in elt: 
    x.append(e[1] * e[0]) 
print "".join(x) 

Danh sách comprehensions là đường đơn giản là cú pháp cho for vòng, mà làm cho một biểu hiện của một chuỗi các câu lệnh .

elt có thể là một đối tượng tùy ý, vì bạn tải nó từ dưa chua, và e tương tự như vậy. Cách sử dụng cho thấy đó là một loại sequence, nhưng nó chỉ có thể là bất cứ thứ gì thực hiện giao thức chuỗi.

+0

Tôi nghĩ bạn có nghĩa là "x.append (e [1] * e [0])" .. –

+0

@Marek: John nói đúng. –

+0

@ John: Chắc chắn rồi, nó đã được sửa. –

4

[e[1] * e[0] for e in elt] là danh sách hiểu, tự đánh giá danh sách bằng cách lặp qua danh sách khác, trong trường hợp này là elt. Mỗi phần tử trong danh sách mới là e[1]*e[0], trong đó e là phần tử tương ứng trong elt.

+0

e có thể là tuple hoặc dict – SilentGhost

+0

e có thể là bất kỳ thứ gì triển khai __getitem__. –

+0

Đó là sự thật, tôi đã thực hiện một giả định xấu. –

1

join() là một phương pháp chuỗi, hoạt động trên thiết bị tách trong chuỗi mới

>>> ':'.join(['ab', 'cd']) 
>>> 'ab:cd' 

và danh sách hiểu là không cần thiết ở đó, máy phát điện sẽ đủ

7

Trước hết, bạn cần phải đặt http: // ở phía trước của URL, ví dụ: xử lý = urllib.urlopen ("http://www.pythonchallenge.com/pc/def/banner.p")

một biểu thức [e cho e trong alist] là một list comprehension mà tạo ra một danh sách các giá trị.

Với chuỗi Python, toán tử * được sử dụng để lặp lại một chuỗi. Hãy thử nhập từng lệnh một vào một thông dịch viên sau đó xem dữ liệu:

>>> data[0] 
[(' ', 95)] 

Điều này cho chúng ta thấy mỗi dòng dữ liệu là một bộ dữ liệu chứa hai phần tử.

Do đó, biểu thức e 1 * e [0] thực sự là chuỗi trong e [0] lặp lại e 1 lần.

Do đó, chương trình sẽ vẽ biểu ngữ.

+0

Nhưng chuyển đổi các phần tử: e [0] = 95 và e [1] = ''. –

+0

cảm ơn cho sự điều chỉnh - Tôi rất quen với việc làm "hợp lý" điều nhân một chuỗi bởi một số nguyên mà tôi đọc nó như là cách đó xung quanh, đặc biệt là vì đó là cách dữ liệu được lưu trữ! –

1

Andy là một câu trả lời tuyệt vời!

Nếu bạn muốn xem tất cả các bước của vòng lặp (với dòng-chia) thử này ra:

for elt in data: 
    for e in elt: 
     print "e[0] == %s, e[1] == %d, which gives us: '%s'" % (e[0], e[1], ''.join(e[1] * e[0])) 
+0

Nó cung cấp một danh sách dài: e [0] ==% s, e [1] ==% d –

+0

@Masi: Cảm ơn vì đã chú ý điều đó. Có thể ký tự ngắt dòng ("\") đang gây ra sự cố. Tôi đã xóa nó khỏi phản hồi. – bernie

2

Câu hỏi bản thân đã được trả lời đầy đủ nhưng tôi muốn thêm rằng một sự hiểu biết danh sách cũng hỗ trợ lọc. dòng ban đầu của bạn

print "".join([e[1] * e[0] for e in elt]) 

thể, làm ví dụ, trở thành

print "".join([e[1] * e[0] for e in elt if len(e) == 2]) 

để chỉ hoạt động trên các mục trong giảng dạy tiếng Anh có hai yếu tố.

+0

Nhận xét đáng giá! – ChuckCottrill

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