web-dev-qa-db-ja.com

Python逆インデックスのみを列挙

列挙されているリストの元の順序を維持しながら、enumerateで指定されたインデックスを逆にしようとしています。

私は次のものを持っていると仮定します:

>> range(5)
[0, 1, 2, 3, 4]

これを列挙すると、次のようになります。

>> list(enumerate(range(5)))
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]

しかし、私はenumerateによって提供されたインデックスを逆にして、次のようにします:

[(4, 0), (3, 1), (2, 2), (1, 3), (0, 4)]

これまでのところ、次のコードがあります。

reversed(list(enumerate(reversed(range(5)))))

これを行うためのきちんとした方法があるかどうか疑問に思っていましたか?

18
rozzy

逆の範囲で代わりに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)
18
Netwave

この解決策があなたにとって良いかどうかはわかりませんが、少なくともそれはより短いです:

>>> [(4 - x, x) for x in range(5)]
[(4, 0), (3, 1), (2, 2), (1, 3), (0, 4)]
7
mandrewcito

リストの長さを取り、そこからインデックスを引きます...

_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()は、汎用イテレーターで機能するため、これを実行できない可能性があります。たとえば、「逆インデックス」さえも持たない無限のイテレータを渡すことができます。

6
RemcoGerlich

リストが長くなく、パフォーマンスエラーが発生しないと仮定すると、list(enumerate(range(5)[::-1]))[::-1]を使用できます。

テスト:

>>> list(enumerate(range(5)[::-1]))[::-1] [(0, 4), (1, 3), (2, 2), (3, 1), (4, 0)]

5
Emil

実際、@ RemcoGerlichと同じロジックを使用していますが、list comprehensionを直接使用しているため、コードは1行になります。

def generatelist(x):
    return [(x-1-i,n) for i,n in enumerate(range(x))]

generatorまたはlist comprehensionを選択するジレンマについては、 here が推奨される方法です。

基本的に、あなたがしているのが一度だけ繰り返している場合は、ジェネレータ式を使用します。生成された結果を保存して使用したい場合は、おそらくリストを理解する方が良いでしょう。

4
MaThMaX
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)
1

Python 2

import itertools

def reversed_enumerate(seq):
    return itertools.izip(reversed(range(len(seq))), reversed(seq))

Python 3

itertools.izipZipに置き換えます:)

1
tzot

数回再利用する場合は、独自のジェネレーターを作成できます。

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))
1
Julien Spronck

使用するすべての場所でlen(lst)-iを使用するだけです。または:

[(len(range(5)) - x, x) for x in range(5)]
1
John

Lenでenumerateを使用できます。

$ 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
$  
0
Venfah Nazir