Python перечисляет только обратный индекс
Я пытаюсь изменить индекс, указанный enumerate
при сохранении первоначального порядка перечисления списка.
Предположим, у меня есть следующее:
>> range(5)
[0, 1, 2, 3, 4]
Если я перечислю это, я получу следующее:
>> list(enumerate(range(5)))
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
Однако я хочу изменить индекс, предоставленный перечислением, чтобы я получил:
[(4, 0), (3, 1), (2, 2), (1, 3), (0, 4)]
Пока у меня есть следующий код:
reversed(list(enumerate(reversed(range(5)))))
Мне просто интересно, есть ли более аккуратный способ сделать это?
8 ответов
Как насчет использования zip вместо обратного диапазона?
>>> zip(range(9, -1, -1), range(10))
[(9, 0), (8, 1), (7, 2), (6, 3), (5, 4), (4, 5), (3, 6), (2, 7), (1, 8), (0, 9)]
>>> def reversedEnumerate(l):
return zip(range(len(l)-1, -1, -1), l)
>>> reversedEnumerate(range(10))
[(9, 0), (8, 1), (7, 2), (6, 3), (5, 4), (4, 5), (3, 6), (2, 7), (1, 8), (0, 9)]
Как подсказывает @julienSpronk, используйте izip
чтобы получить генератор, а также xrange
:
import itertools
>>> import itertools
>>> def reversedEnumerate(l):
... return itertools.izip(xrange(len(l)-1, -1, -1), l)
...
>>> reversedEnumerate(range(10))
<itertools.izip object at 0x03749760>
>>> for i in reversedEnumerate(range(10)):
... print i
...
(9, 0)
(8, 1)
(7, 2)
(6, 3)
(5, 4)
(4, 5)
(3, 6)
(2, 7)
(1, 8)
(0, 9)
Просто возьмите длину вашего списка и вычтите индекс из этого...
L = range(5)
for i, n in L:
my_i = len(L) -1 - i
...
Или если вам действительно нужен генератор:
def reverse_enumerate(L):
# Only works on things that have a len()
l = len(L)
for i, n in enumerate(L):
yield l-i-1, n
enumerate()
не может сделать это, так как он работает с общими итераторами. Например, вы можете передать его бесконечным итераторам, которые даже не имеют "обратного индекса".
Я не знаю, подходит ли вам это решение, но, по крайней мере, оно короче:
>>> [(4 - x, x) for x in range(5)]
[(4, 0), (3, 1), (2, 2), (1, 3), (0, 4)]
Если ваш список не длинный и вы не столкнетесь с ошибками производительности, вы можете использовать list(enumerate(range(5)[::-1]))[::-1]
,
Тестовое задание:
>>> list(enumerate(range(5)[::-1]))[::-1]
[(0, 4), (1, 3), (2, 2), (3, 1), (4, 0)]
На самом деле я использую ту же логику, что и @RemcoGerlich, но я использую list comprehension
непосредственно, что делает код теперь 1-лайн:
def generatelist(x):
return [(x-1-i,n) for i,n in enumerate(range(x))]
Относительно дилеммы выбора generator
или же list comprehension
Вот предложенный способ:
В основном, используйте выражение генератора, если все, что вы делаете, это итерация один раз. Если вы хотите сохранить и использовать сгенерированные результаты, то вам, вероятно, лучше понять список.
Python 2
import itertools
def reversed_enumerate(seq):
return itertools.izip(reversed(range(len(seq))), reversed(seq))
Python 3
Замена zip
за itertools.izip
:)
Если вы собираетесь использовать его несколько раз, вы можете создать свой собственный генератор:
def reverse_enum(lst):
for j, item in enumerate(lst):
yield len(lst)-1-j, item
print list(reverse_enum(range(5)))
# [(4, 0), (3, 1), (2, 2), (1, 3), (0, 4)]
или же
def reverse_enum(lst):
return ((len(lst)-1-j, item) for j, item in enumerate(lst))
Мы можем использовать enumerate с len:
$ cat enumerate.py
arr = ['stone', 'cold', 'steve', 'austin']
for i, val in enumerate(arr):
print ("enu {} val {}".format(i, val))
for i, val in enumerate(arr):
print ("enu {} val {}".format(len(arr) - i - 1, val))
$ python enumerate.py
enu 0 val stone
enu 1 val cold
enu 2 val steve
enu 3 val austin
enu 3 val stone
enu 2 val cold
enu 1 val steve
enu 0 val austin
$
Просто использовать len(lst)-i
везде я использую. или же:
[(len(range(5)) - x, x) for x in range(5)]
values = 'abcde'
for i, value in zip(reversed(range(len(values))), values):
print(i, value)
Объяснение:
values = 'abcde'
values_len = len(values) # 5
indexes = range(values_len) # [0, 1, 2, 3, 4]
reversed_indexes = reversed(indexes) # [4, 3, 2, 1, 0]
# combine reversed indexes and values
reversed_enumerator = zip(reversed_indexes, values)
for i, value in reversed_enumerator:
print(i, value)