2010-08-03 45 views
9

Giả sử tôi có danh sách object_list chứa các đối tượng.Python kiểm tra chỉ mục đầu tiên và cuối cùng của danh sách

Tôi muốn kiểm tra xem lần lặp hiện tại của tôi có đang ở lần đầu tiên hay lần cuối cùng.

for object in object_list: 
    do_something 
    if first_indexed_element: 
     do_something_else 
    if last_indexed_element: 
     do_another_thing 

Làm cách nào để đạt được điều này? Tôi biết rằng tôi có thể sử dụng phạm vi và đếm chỉ số nhưng nếu cảm thấy vụng về.

Trân

Trả lời

12
li = iter(object_list) 

obj = next(li) 

do_first_thing_with(obj) 

while True: 
    try: 
     do_something_with(obj) 
     obj = next(li) 
    except StopIteration: 
     do_final_thing_with(obj) 
     break 
+1

+1 để sử dụng trình lặp thay vì số chỉ mục. Trong câu hỏi của OP, tất cả các đối tượng được xử lý với do_something, và xử lý đặc biệt được thực hiện với đầu tiên và cuối cùng. Trong mã của bạn, bạn thực hiện xử lý đặc biệt cho mục đầu tiên, nhưng không xử lý từng mục. Tôi nghĩ bạn chỉ cần đảo ngược 2 câu lệnh trong mệnh đề try: để có được hành vi mong muốn. – PaulMcG

+1

Khá phức tạp. Không chính xác tác giả muốn ('do_first_thing_with' nên được gọi sau' do_something_with' đầu tiên). –

+0

có khả năng là giải pháp hiệu quả nhất (+1), nhưng tiếc là không phải là rất ngắn gọn/dễ dàng để grok. – wds

14

Bạn có thể sử dụng enumerate():

for i, obj in enumerate(object_list): 
    do_something 
    if i == 0: 
     do_something_else 
    if i == len(object_list) - 1: 
     do_another_thing 

Nhưng thay vì kiểm tra trong mỗi lần lặp mà đối tượng bạn đang đối phó với, có lẽ một cái gì đó như thế này là tốt hơn:

def do_with_list(object_list): 
    for obj in object_list: 
     do_something(obj) 
    do_something_else(object_list[0]) 
    do_another_thing(object_list[-1]) 

Hãy tưởng tượng bạn có một danh sách 100 đối tượng, sau đó bạn thực hiện 198 so sánh không cần thiết, bởi vì phần tử hiện tại không thể là phần tử đầu tiên hoặc cuối cùng trong danh sách.

Nhưng nó phụ thuộc vào việc các câu lệnh phải được thực hiện theo một thứ tự nhất định và những gì chúng đang thực hiện.


Btw. không shadow object, nó đã là một định danh bằng Python;)

+1

'i' sẽ không bao giờ bằng' len (object_list) '. – Amber

+0

@Amber: Đúng, cảm ơn –

3
for index, obj in enumerate(object_list): 
    do_something 
    if index == 0: 
     do_something_else 
    if index == len(object_list)-1: 
     do_another_thing 
+0

Sẽ ngắt nếu object_list là trình lặp. Tốt hơn là viết mã sẽ hoạt động với tất cả các lần lặp lại, không chỉ danh sách. –

+0

Không phải khi nó làm cho mã phức tạp hơn nhiều để đọc và bạn biết bạn sẽ làm việc với các danh sách. – Amber

0

Bạn chỉ cần sử dụng một bộ đếm, không cần khoảng:

Hãy nói rằng truy cập của bạn là cpt.

if cpt == 0: 
    print "first" 

if cpt == len(object_list) - 1: 
    print "last" 

chỉnh sửa: giải pháp enumerate có thể thanh lịch hơn.

0
  1. Bạn có thể tạo i = 0 và sau đó là i + + trong các lần lặp. Vì vậy, nếu i == 0 thì đó là lần lặp đầu tiên, nếu i == list.size() - 1 thì nó là lần lặp cuối cùng.
  2. Phải có smth như indexOf (đối tượng), trả về vị trí của phần tử trong danh sách. nếu 0 - lần lặp đầu tiên, nếu size() - 1 hơn last. Nhưng nó đắt.
  3. sử dụng liệt kê. Xem bài đăng của Amber hoặc Felix.
  4. so sánh phần tử hiện tại với danh sách [0] và danh sách [-1]. trong trường hợp đầu tiên - lần lặp đầu tiên, trong trường hợp cuối cùng - lần lặp cuối cùng. Nó cũng rất đắt.

Vì vậy, tôi muốn chọn 1 hoặc 3.
PS: list.size() được len (list) của khóa học.

+0

Tại sao nên 4. đắt tiền? Truy cập danh sách phải là 'O (1)'. –

+0

Không biết O (1) là gì, nhưng so sánh các đối tượng tùy chỉnh, imho, luôn chậm hơn khi so sánh các số (ngay cả khi chúng là các đối tượng). Hơn nữa, trong trường hợp này, bạn nên cung cấp các quy tắc bình đẳng, có thể khá phức tạp. Hơn nữa, danh sách có thể chứa các bản sao, vì vậy nó có thể gây ra lỗi (nó là quan điểm khác nhau, tuy nhiên bạn phải xem xét nó). – foret

+0

Hơn nữa! : khi bạn cố gắng lấy phần tử từ danh sách, python đầu tiên tìm danh sách, sau đó tìm phần tử ở chỉ mục. nếu bạn sử dụng số, nó chỉ phải tìm số, vì vậy 1 hoạt động ít hơn. imho - i don; t biết python internals. – foret

1
first = True 
for o in object_list: 
    do_something(o) 
    if first: 
     first = False 
     do_something_with_first(o) 
if 'o' in locals(): 
    do_something_with_last(o) 
Các vấn đề liên quan