Vì vậy, tôi có thể bắt đầu từ len(collection)
và kết thúc collection[0]
.
Tôi cũng muốn có thể truy cập vào chỉ số vòng lặp.
Vì vậy, tôi có thể bắt đầu từ len(collection)
và kết thúc collection[0]
.
Tôi cũng muốn có thể truy cập vào chỉ số vòng lặp.
Câu trả lời:
Sử dụng reversed()
chức năng tích hợp:
>>> a = ["foo", "bar", "baz"]
>>> for i in reversed(a):
... print(i)
...
baz
bar
foo
Để truy cập chỉ mục gốc, hãy sử dụng enumerate()
trong danh sách của bạn trước khi chuyển nó tới reversed()
:
>>> for i, e in reversed(list(enumerate(a))):
... print(i, e)
...
2 baz
1 bar
0 foo
Vì enumerate()
trả về một máy phát và máy phát không thể đảo ngược, bạn cần chuyển đổi nó thành máy phát list
trước.
reversed()
không sửa đổi danh sách. reversed()
không tạo một bản sao của danh sách (nếu không nó sẽ yêu cầu bộ nhớ bổ sung O (N)). Nếu bạn cần sửa đổi danh sách sử dụng alist.reverse()
; nếu bạn cần một bản sao của danh sách theo thứ tự đảo ngược sử dụng alist[::-1]
.
Bạn có thể làm:
for item in my_list[::-1]:
print item
(Hoặc bất cứ điều gì bạn muốn làm trong vòng lặp for.)
Các [::-1]
lát cắt đảo ngược danh sách trong vòng lặp for (nhưng thực tế sẽ không sửa đổi danh sách của bạn "vĩnh viễn").
[::-1]
tạo một bản sao nông, do đó nó không thay đổi mảng không "vĩnh viễn" hay "tạm thời".
0
, có thể -1
, vì vậy kết thúc khi bắt đầu ) và bước : -1
(lặp lại qua danh sách, 1
mục tại một thời điểm).
reversed()
Nếu bạn cần chỉ mục vòng lặp và không muốn duyệt qua toàn bộ danh sách hai lần hoặc sử dụng thêm bộ nhớ, tôi sẽ viết một trình tạo.
def reverse_enum(L):
for index in reversed(xrange(len(L))):
yield index, L[index]
L = ['foo', 'bar', 'bas']
for index, item in reverse_enum(L):
print index, item
reversed(xrange(len(L)))
tạo ra các chỉ số tương tự như xrange(len(L)-1, -1, -1)
.
for index, item in enumerate(reversed(L)): print len(L)-1-index, item
Nó có thể được thực hiện như thế này:
cho i trong phạm vi (len (bộ sưu tập) -1, -1, -1): bộ sưu tập in [i] # in (bộ sưu tập [i]) cho python 3. +
Vì vậy, dự đoán của bạn đã khá gần :) Một chút lúng túng nhưng về cơ bản nó nói: bắt đầu với 1 ít hơn len(collection)
, tiếp tục cho đến khi bạn đến ngay trước -1, theo các bước của -1.
Fyi, help
chức năng này rất hữu ích vì nó cho phép bạn xem các tài liệu cho một cái gì đó từ bảng điều khiển Python, ví dụ:
help(range)
-1
. Tôi chỉ muốn nóireversed(xrange(len(collection)))
Hàm reversed
dựng sẵn rất tiện dụng:
for item in reversed(sequence):
Các tài liệu cho đảo ngược giải thích những hạn chế của nó.
Đối với các trường hợp tôi phải đi ngược lại trình tự cùng với chỉ mục (ví dụ: để sửa đổi tại chỗ thay đổi độ dài chuỗi), tôi có chức năng này xác định mô-đun codeutil của tôi:
import itertools
def reversed_enumerate(sequence):
return itertools.izip(
reversed(xrange(len(sequence))),
reversed(sequence),
)
Điều này tránh tạo ra một bản sao của chuỗi. Rõ ràng, những reversed
hạn chế vẫn được áp dụng.
Làm thế nào về mà không tạo lại một danh sách mới, bạn có thể làm bằng cách lập chỉ mục:
>>> foo = ['1a','2b','3c','4d']
>>> for i in range(len(foo)):
... print foo[-(i+1)]
...
4d
3c
2b
1a
>>>
HOẶC LÀ
>>> length = len(foo)
>>> for i in range(length):
... print foo[length-i-1]
...
4d
3c
2b
1a
>>>
Ngoài ra, bạn có thể sử dụng các hàm "phạm vi" hoặc "đếm". Như sau:
a = ["foo", "bar", "baz"]
for i in range(len(a)-1, -1, -1):
print(i, a[i])
3 baz
2 bar
1 foo
Bạn cũng có thể sử dụng "đếm" từ itertools như sau:
a = ["foo", "bar", "baz"]
from itertools import count, takewhile
def larger_than_0(x):
return x > 0
for x in takewhile(larger_than_0, count(3, -1)):
print(x, a[x-1])
3 baz
2 bar
1 foo
3 foo\n2 bar\n1 baz
Sử dụng list.reverse()
và sau đó lặp đi lặp lại như bình thường.
cho những gì đáng giá bạn cũng có thể làm như thế này. rất đơn giản.
a = [1, 2, 3, 4, 5, 6, 7]
for x in xrange(len(a)):
x += 1
print a[-x]
print a[-(x+1)]
và tránh gán lại chỉ số trong phần thân của vòng lặp.
Một cách biểu cảm để đạt được reverse(enumerate(collection))
trong python 3:
zip(reversed(range(len(collection))), reversed(collection))
trong trăn 2:
izip(reversed(xrange(len(collection))), reversed(collection))
Tôi không chắc tại sao chúng ta không có một tốc ký cho việc này, vd.:
def reversed_enumerate(collection):
return zip(reversed(range(len(collection))), reversed(collection))
hoặc tại sao chúng ta không có reversed_range()
Nếu bạn cần chỉ mục và danh sách của bạn nhỏ, cách dễ đọc nhất là làm reversed(list(enumerate(your_list)))
như câu trả lời được chấp nhận nói. Nhưng điều này tạo ra một bản sao của danh sách của bạn, vì vậy nếu danh sách của bạn chiếm một phần lớn bộ nhớ, bạn sẽ phải trừ chỉ mục được trả về enumerate(reversed())
từlen()-1
.
Nếu bạn chỉ cần làm một lần:
a = ['b', 'd', 'c', 'a']
for index, value in enumerate(reversed(a)):
index = len(a)-1 - index
do_something(index, value)
hoặc nếu bạn cần làm điều này nhiều lần, bạn nên sử dụng một trình tạo:
def enumerate_reversed(lyst):
for index, value in enumerate(reversed(lyst)):
index = len(lyst)-1 - index
yield index, value
for index, value in enumerate_reversed(a):
do_something(index, value)
chức năng đảo ngược có ích ở đây:
myArray = [1,2,3,4]
myArray.reverse()
for x in myArray:
print x
Bạn có thể sử dụng một chỉ mục tiêu cực trong một vòng lặp for thông thường:
>>> collection = ["ham", "spam", "eggs", "baked beans"]
>>> for i in range(1, len(collection) + 1):
... print(collection[-i])
...
baked beans
eggs
spam
ham
Để truy cập vào chỉ mục như thể bạn đang lặp đi lặp lại qua một bản sao đảo ngược của bộ sưu tập, hãy sử dụng i - 1
:
>>> for i in range(1, len(collection) + 1):
... print(i-1, collection[-i])
...
0 baked beans
1 eggs
2 spam
3 ham
Để truy cập chỉ mục gốc, không đảo ngược, sử dụng len(collection) - i
:
>>> for i in range(1, len(collection) + 1):
... print(len(collection)-i, collection[-i])
...
3 baked beans
2 eggs
1 spam
0 ham
Tôi nghĩ rằng cách thanh lịch nhất là chuyển đổi enumerate
và reversed
sử dụng trình tạo sau
(-(ri+1), val) for ri, val in enumerate(reversed(foo))
tạo ra sự đảo ngược của enumerate
trình vòng lặp
Thí dụ:
foo = [1,2,3]
bar = [3,6,9]
[
bar[i] - val
for i, val in ((-(ri+1), val) for ri, val in enumerate(reversed(foo)))
]
Kết quả:
[6, 4, 2]
Các câu trả lời khác là tốt, nhưng nếu bạn muốn làm theo kiểu hiểu danh sách
collection = ['a','b','c']
[item for item in reversed( collection ) ]
input_list = ['foo','bar','baz']
for i in range(-1,-len(input_list)-1,-1)
print(input_list[i])
Tôi nghĩ rằng đây cũng là một cách đơn giản để làm điều đó ... đọc từ cuối và tiếp tục giảm dần cho đến khi danh sách kéo dài, vì chúng tôi không bao giờ thực hiện chỉ số "kết thúc" do đó cũng thêm -1
Giả sử nhiệm vụ là tìm phần tử cuối cùng thỏa mãn một số điều kiện trong danh sách (nghĩa là lần đầu tiên khi nhìn về phía sau), tôi nhận được các số sau:
>>> min(timeit.repeat('for i in xrange(len(xs)-1,-1,-1):\n if 128 == xs[i]: break', setup='xs, n = range(256), 0', repeat=8))
4.6937971115112305
>>> min(timeit.repeat('for i in reversed(xrange(0, len(xs))):\n if 128 == xs[i]: break', setup='xs, n = range(256), 0', repeat=8))
4.809093952178955
>>> min(timeit.repeat('for i, x in enumerate(reversed(xs), 1):\n if 128 == x: break', setup='xs, n = range(256), 0', repeat=8))
4.931743860244751
>>> min(timeit.repeat('for i, x in enumerate(xs[::-1]):\n if 128 == x: break', setup='xs, n = range(256), 0', repeat=8))
5.548468112945557
>>> min(timeit.repeat('for i in xrange(len(xs), 0, -1):\n if 128 == xs[i - 1]: break', setup='xs, n = range(256), 0', repeat=8))
6.286104917526245
>>> min(timeit.repeat('i = len(xs)\nwhile 0 < i:\n i -= 1\n if 128 == xs[i]: break', setup='xs, n = range(256), 0', repeat=8))
8.384078979492188
Vì vậy, lựa chọn xấu nhất xrange(len(xs)-1,-1,-1)
là nhanh nhất.