Làm thế nào để lặp qua tất cả trừ mục cuối cùng của danh sách?


160

Tôi muốn lặp qua một danh sách kiểm tra từng mục theo mục đó.

Có cách nào tôi có thể lặp qua tất cả trừ mục cuối cùng sử dụng cho x trong y không? Tôi muốn làm điều đó mà không sử dụng các chỉ mục nếu tôi có thể.

Ghi chú

freespace đã trả lời câu hỏi thực tế của tôi, đó là lý do tại sao tôi chấp nhận câu trả lời, nhưng SilentGhost đã trả lời câu hỏi tôi nên hỏi.

Xin lỗi vì sự nhầm lẫn.

Câu trả lời:


315
for x in y[:-1]

Nếu ylà một máy phát điện, thì ở trên sẽ không hoạt động.


Điều đó trả lời câu hỏi của tôi, cảm ơn, nhưng tôi quên hỏi làm thế nào tôi có được món hàng sau x. Điều này có thể không?
David Sykes

3
- 1 Tôi không nghĩ rằng trả lời câu hỏi. Nó không so sánh từng mục với mục tiếp theo. - odwl 0 giây trước
odwl

4
Tôi nghĩ rằng tôi đã làm. Tác giả cho biết anh ta muốn làm X, sau đó hỏi làm thế nào anh ta có thể làm Y. Tôi đã trả lời làm thế nào anh ta có thể làm Y. Rằng anh ta chấp nhận câu trả lời của tôi sẽ cho biết tôi đã trả lời câu hỏi anh ta hỏi, nếu không phải là câu hỏi anh ta thực sự muốn hỏi. Asker được chào đón để hạ thấp câu trả lời này.
freespace

7
Chỉ vì OP nên đã hỏi một câu hỏi khác trong lần đầu tiên, không có nghĩa là câu hỏi của anh ấy và câu trả lời này không hữu ích cho người khác. +1
Giáo sư Falken

1
Bạn đề cập rằng điều này không làm việc cho máy phát điện. Điều gì thay thế khi ylà một máy phát điện?
Joost

50

cách dễ nhất để so sánh mục trình tự với các mục sau:

for i, j in zip(a, a[1:]):
     # compare i (the current) to j (the following)

15
Điều này trả lời câu hỏi tôi muốn tôi đã hỏi. Cảm ơn
David Sykes

3
Trên thực tế, bạn có thể bỏ qua lát đầu tiên, vì zip cắt ngắn danh sách dài hơn với độ dài ngắn hơn. Điều này sẽ giúp bạn tiết kiệm một danh sách tạo. (Chỉ trong trường hợp bạn đang đối phó với các danh sách khổng lồ Nhưng trong trường hợp đó, bạn nên làm theo cách tiếp cận Ants Aasma, mà không sao chép bất cứ điều gì..)
bayer

19

Nếu bạn muốn có được tất cả các phần tử trong cặp trình tự một cách khôn ngoan, hãy sử dụng phương pháp này (hàm cặp là từ các ví dụ trong mô-đun itertools).

from itertools import tee, izip, chain

def pairwise(seq):
    a,b = tee(seq)
    b.next()
    return izip(a,b)

for current_item, next_item in pairwise(y):
    if compare(current_item, next_item):
        # do what you have to do

Nếu bạn cần so sánh giá trị cuối cùng với một số giá trị đặc biệt, hãy xâu chuỗi giá trị đó đến cuối

for current, next_item in pairwise(chain(y, [None])):

xin lưu ý rằng việc sử dụng tiếp theo cho bóng tên biến có sẵn
SilentGhost

1
Cá nhân tôi không bận tâm đến việc xây dựng các nội dung ít được sử dụng khi phạm vi của biến nhỏ và tên này phù hợp để dễ đọc. Tuy nhiên, đã chỉnh sửa tên biến để duy trì thực hành mã hóa tốt.
Kiến Aasma

5

nếu bạn muốn so sánh mục thứ n với mục thứ n + 1 trong danh sách, bạn cũng có thể làm với

>>> for i in range(len(list[:-1])):
...     print list[i]>list[i+1]

lưu ý rằng không có mã hóa cứng đang diễn ra ở đó. Điều này sẽ ổn trừ khi bạn cảm thấy khác.


3
Bạn có thể thay thế len (danh sách [: - 1]) bằng len (danh sách) - 1 để tránh sao chép danh sách. Và tránh sử dụng một biến được gọi là danh sách ...
Remy Blank

2

Để so sánh từng mục với mục tiếp theo trong trình lặp mà không cần khởi tạo danh sách:

import itertools
it = (x for x in range(10))
data1, data2 = itertools.tee(it)
data2.next()
for a, b in itertools.izip(data1, data2):
  print a, b

2
đó chính xác là những gì được đề xuất bởi Ants Aasma stackoverflow.com/questions/914715/
SilentGhost

1

Điều này trả lời những gì OP nên hỏi , tức là duyệt qua một danh sách so sánh các yếu tố liên tiếp ( câu trả lời SilentGhost xuất sắc ), nhưng được khái quát cho bất kỳ nhóm nào ( n-gram ): 2, 3, ... n:

zip(*(l[start:] for start in range(0, n)))

Ví dụ:

l = range(0, 4)  # [0, 1, 2, 3]

list(zip(*(l[start:] for start in range(0, 2)))) # == [(0, 1), (1, 2), (2, 3)]
list(zip(*(l[start:] for start in range(0, 3)))) # == [(0, 1, 2), (1, 2, 3)]
list(zip(*(l[start:] for start in range(0, 4)))) # == [(0, 1, 2, 3)]
list(zip(*(l[start:] for start in range(0, 5)))) # == []

Giải thích:

  • l[start:] tạo danh sách aa / trình tạo bắt đầu từ chỉ mục start
  • *listhoặc *generator: chuyển tất cả các phần tử cho hàm kèm theo zipnhư thể nó được viếtzip(elem1, elem2, ...)

Ghi chú:

AFAIK, mã này là lười biếng như nó có thể được. Không được kiểm tra.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.