Доступ к индексу в циклах for?
Как получить доступ к самому индексу для списка, подобного следующему?
ints = [8, 23, 45, 12, 78]
Когда я перебираю его, используя цикл for
, как мне получить доступ к индексу цикла, от 1 до 5 в этом случае?
23 ответа
Использование дополнительной переменной состояния, такой как индексная переменная (которую вы обычно используете в таких языках, как C или PHP), считается непифоническим.
Лучшим вариантом является использование встроенной функции enumerate()
, доступно в Python 2 и 3:
for idx, val in enumerate(ints):
print(idx, val)
Ознакомьтесь с PEP 279 , чтобы узнать больше.
Как использовать цикл for, как мне получить доступ к индексу цикла, в данном случае от 1 до 5?
Используйте enumerate
, чтобы получить индекс для элемента во время итерации:
for index, item in enumerate(items):
print(index, item)
И обратите внимание, что индексы Python начинаются с нуля, поэтому вы получите от 0 до 4 с вышеописанным. Если вы хотите считать от 1 до 5, сделайте следующее:
for count, item in enumerate(items, start=1):
print(count, item)
Унидиоматический поток управления
То, что вы просите, это Pythonic-эквивалент следующего: алгоритм, который будет использовать большинство программистов на языках нижнего уровня:
index = 0 # Python's indexing starts at zero for item in items: # Python's for loops are a "for each" loop print(index, item) index += 1
Или в языках, в которых нет цикла for-each:
index = 0 while index < len(items): print(index, items[index]) index += 1
или иногда более часто (но неидиоматически) в Python:
for index in range(len(items)): print(index, items[index])
Используйте функцию перечисления
Python enumerate
function уменьшает визуальный беспорядок, скрывая учет индексов и инкапсулируя итерируемое в другое итерируемое (enumerate
), который возвращает кортеж из двух элементов индекса и элемент, который будет обеспечивать исходная итерация. Это выглядит так:
for index, item in enumerate(items, start=0): # default is zero
print(index, item)
Этот пример кода довольно хорошо подходит для канонический пример различия между кодом, который является идиоматическим для Python, и кодом, который не является. Идиоматический код является сложным (но не сложным) Python, написанным так, как он был предназначен для использования. Разработчики языка ожидают идиоматического кода, что означает, что обычно этот код не только более читабелен, но и более эффективен.
Получение подсчета
Даже если вам не нужны индексы по ходу работы, но вам нужно количество итераций (иногда желательно), вы можете начать с 1
и ваш номер будет последним.
for count, item in enumerate(items, start=1): # default is zero
print(item)
print('there were {0} items printed'.format(count))
Счет, кажется, больше того, что вы намереваетесь просить (в отличие от индекса), когда вы сказали, что хотите от 1 до 5.
Разбивка - пошаговое объяснение
Чтобы разбить эти примеры, скажем, у нас есть список элементов, которые мы хотим перебрать с индексом:
items = ['a', 'b', 'c', 'd', 'e']
Теперь мы передаем эту итерацию для перечисления, создавая объект перечисления:
enumerate_object = enumerate(items) # the enumerate object
Мы можем извлечь первый элемент из этой итерации, который мы поместим в цикл с помощью функции next
:
iteration = next(enumerate_object) # first iteration from enumerate
print(iteration)
И мы видим, что мы получаем кортеж 0
, первый индекс и 'a'
, первый элемент:
(0, 'a')
мы можем использовать то, что называется " распаковка последовательности "чтобы извлечь элементы из этого кортежа:
index, item = iteration
# 0, 'a' = (0, 'a') # essentially this.
и когда мы проверяем index
, мы обнаруживаем, что он ссылается на первый индекс 0 и item
относится к первому элементу, 'a'
.
>>> print(index)
0
>>> print(item)
a
Заключение
- Индексы Python начинаются с нуля
- Чтобы получить эти индексы из итерируемого при его итерации по нему, используйте функцию перечисления
- Использование перечисления идиоматическим способом (вместе с распаковкой кортежей) создает код, который более читабелен и удобен в обслуживании:
Так сделайте это:
for index, item in enumerate(items, start=0): # Python indexes start at zero
print(index, item)
Довольно просто запустить его из 1
, кроме 0
:
for index, item in enumerate(iterable, start=1):
print index, item
Примечание
Важный совет, хотя и немного вводящий в заблуждение, поскольку index
будет tuple
(idx, item)
здесь.
Хорошо идти.
for i in range(len(ints)):
print i, ints[i]
Как правило, в Python есть несколько способов сделать это. Во всех примерах предположим: lst = [1, 2, 3, 4, 5]
1. Использование enumerate ( считается наиболее идиоматическим )
for index, element in enumerate(lst):
# do the things that need doing here
На мой взгляд, это также самый безопасный вариант, потому что исключена вероятность перехода в бесконечную рекурсию. И элемент, и его индекс хранятся в переменных, и нет необходимости писать дополнительный код чтобы получить доступ к элементу.
2. Создание переменной для хранения индекса ( с использованием for
)
for index in range(len(lst)): # or xrange
# you will have to write extra code to get the element
3. Создание переменной для хранения индекса ( с использованием while
)
index = 0
while index < len(lst):
# you will have to write extra code to get the element
index += 1 # escape infinite recursion
4. Всегда есть другой способ
Как объяснено ранее, есть другие способы сделать это, которые не были объяснены здесь, и они могут даже применить больше в других ситуациях. например , используя itertools.chain
с for. Он лучше обрабатывает вложенные циклы, чем другие примеры.
Старомодный способ:
for ix in range(len(ints)):
print ints[ix]
Понимание списка:
[ (ix, ints[ix]) for ix in range(len(ints))]
>>> ints
[1, 2, 3, 4, 5]
>>> for ix in range(len(ints)): print ints[ix]
...
1
2
3
4
5
>>> [ (ix, ints[ix]) for ix in range(len(ints))]
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
>>> lc = [ (ix, ints[ix]) for ix in range(len(ints))]
>>> for tup in lc:
... print tup
...
(0, 1)
(1, 2)
(2, 3)
(3, 4)
(4, 5)
>>>
Самый быстрый способ получить доступ к индексам списка в цикле в Python 2.7 - это использовать метод диапазона для небольших списков и перечислять метод для списков среднего и большого размера.
Ознакомьтесь с различными подходами , которые можно использовать для перебора списка и доступа к значению индекса и их метрик производительности (что, я думаю, будет полезно для вас) в примерах кода ниже:
from timeit import timeit
# Using range
def range_loop(iterable):
for i in range(len(iterable)):
1 + iterable[i]
# Using xrange
def xrange_loop(iterable):
for i in xrange(len(iterable)):
1 + iterable[i]
# Using enumerate
def enumerate_loop(iterable):
for i, val in enumerate(iterable):
1 + val
# Manual indexing
def manual_indexing_loop(iterable):
index = 0
for item in iterable:
1 + item
index += 1
См. показатели производительности для каждого метода ниже:
from timeit import timeit
def measure(l, number=10000):
print "Measure speed for list with %d items" % len(l)
print "xrange: ", timeit(lambda :xrange_loop(l), number=number)
print "range: ", timeit(lambda :range_loop(l), number=number)
print "enumerate: ", timeit(lambda :enumerate_loop(l), number=number)
print "manual_indexing: ", timeit(lambda :manual_indexing_loop(l), number=number)
measure(range(1000))
# Measure speed for list with 1000 items
# xrange: 0.758321046829
# range: 0.701184988022
# enumerate: 0.724966049194
# manual_indexing: 0.894635915756
measure(range(10000))
# Measure speed for list with 100000 items
# xrange: 81.4756360054
# range: 75.0172479153
# enumerate: 74.687623024
# manual_indexing: 91.6308541298
measure(range(10000000), number=100)
# Measure speed for list with 10000000 items
# xrange: 82.267786026
# range: 84.0493988991
# enumerate: 78.0344707966
# manual_indexing: 95.0491430759
В результате, использование метода range
является самым быстрым из списка с 1000 элементами. Для списка с размером> 10 000 предметов enumerate
- победитель.
Добавление нескольких полезных ссылок ниже:
Я не знаю, является ли следующее Pythonic или нет, но он использует функцию Python enumerate
и печатает индекс и значение.
int_list = [8, 23, 45, 12, 78]
for index, value in enumerate(int_list):
print(index, value)
Вывод:
0 8
1 23
2 45
3 12
4 78
ints = [9, 23, 45, 12, 78]
ints.extend([1,2,3,4,5,6,7,8])
for idx, val in enumerate(ints):
print(idx,val)
Таким образом, вы можете расширить список. Расширить означает, что вы можете добавлять несколько значений одновременно.
Чтобы добавить этот список, вы должны написать приведенный ниже код:
ints = [9, 23, 45, 12, 78]
ints.append([1])
for idx, val in enumerate(ints):
print(idx,val)
Таким образом, вы можете добавлять одно значение за раз. Если вы напишите ints.append([1])
, это создаст подсписок для этого элемента.
Прежде всего, индексы будут от 0 до 4. Языки программирования начинают считать с 0; не забывайте об этом, иначе вы встретите исключение индекса за пределами границ. Все, что вам нужно в цикле for, это переменная, считающая от 0 до 4, например:
for x in range(0, 5):
Имейте в виду, что я написал от 0 до 5, потому что цикл останавливается на один номер до макс. :)
Чтобы получить значение индекса, используйте
list[index]
Согласно этому обсуждению: http://bytes.com/topic/python/answers/464012-объекты-список индекс
Итерация счетчика циклов
Текущая идиома для циклического перемещения по индексам использует встроенную функцию 'range':
for i in range(len(sequence)):
# work with index i
Цикл по обоим элементам и индексам может быть достигнут либо с помощью старой идиомы, либо с помощью новой встроенной функции 'zip' [2]:
for i in range(len(sequence)):
e = sequence[i]
# work with index i and element e
или
for i, e in zip(range(len(sequence)), sequence):
# work with index i and element e
Вы можете сделать это с помощью этого кода:
ints = [8, 23, 45, 12, 78]
index = 0
for value in (ints):
index +=1
print index, value
Используйте этот код, если вам нужно сбросить значение индекса в конце цикла:
ints = [8, 23, 45, 12, 78]
index = 0
for value in (ints):
index +=1
print index, value
if index >= len(ints)-1:
index = 0
Лучшее решение этой проблемы - использовать встроенную функцию Python enumerate .
перечислить вернуть кортеж
первое значение - индекс
Второе значение - элемент массива с этим индексом
In [1]: ints = [8, 23, 45, 12, 78]
In [2]: for idx, val in enumerate(ints):
...: print(idx, val)
...:
(0, 8)
(1, 23)
(2, 45)
(3, 12)
(4, 78)
Если в списке нет повторяющихся значений:
for i in ints:
indx = ints.index(i)
print(i,indx)
В противном случае используйте enumerate
.
for counter, value in enumerate(ints):
print(counter, value)
ИЛИ используйте ниже:
for counter in range(len(ints)):
print(counter, ints[counter])
Вы также можете попробовать это:
data = ['itemA.ABC', 'itemB.defg', 'itemC.drug', 'itemD.ashok']
x = []
for (i, item) in enumerate(data):
a = (i, str(item).split('.'))
x.append(a)
for index, value in x:
print(index, value)
Вывод
0 ['itemA', 'ABC']
1 ['itemB', 'defg']
2 ['itemC', 'drug']
3 ['itemD', 'ashok']
В вашем вопросе вы пишете «как мне получить доступ к индексу цикла, в данном случае от 1 до 5?»
Однако индекс для списка запускается с нуля. Итак, нам нужно знать, действительно ли вам нужен индекс и элемент для каждого элемента в списке, или вы действительно хотите, чтобы числа начинались с 1. К счастью, в python это легко сделать и тем, и другим. >
Во-первых, чтобы уточнить, функция перечисления итеративно возвращает индекс и соответствующий элемент для каждого элемента в списке.
alist = [ 1, 2, 3, 4, 5 ]
for n,a in enumerate(alist):
print( "%d %d"%(n,a) )
Выход для вышеупомянутого -
0 1
1 2
2 3
3 4
4 5
Обратите внимание, что индекс начинается с 0. Этот вид индексации распространен среди современных языков программирования, включая Python и C.
Если вы хотите, чтобы ваш цикл занимал часть списка, вы можете использовать стандартный синтаксис python для части списка. Например, чтобы перейти от второго элемента в списке до последнего элемента, но не включая последний, вы можете использовать
for n,a in enumerate(alist[1:-1]):
print( "%d %d"%(n,a) )
Обратите внимание, что снова выходной индекс начинается с 0,
0 2
1 3
2 4
Это подводит нас к переключателю start = n для enumerate (). Это просто смещает индекс, вы можете эквивалентно просто добавить число к индексу внутри цикла.
for n,a in enumerate(alist,start=1):
print( "%d %d"%(n,a) )
для которого вывод
1 1
2 2
3 3
4 4
5 5
Вы можете использовать метод index
ints = [8, 23, 45, 12, 78]
inds = [ints.index(i) for i in ints]
ИЗМЕНИТЬ
В комментарии отмечено, что этот метод не работает, если в ints
есть дубликаты, метод ниже должен работать для любых значений в ints
:
ints = [8, 8, 8, 23, 45, 12, 78]
inds = [tup[0] for tup in enumerate(ints)]
Или в качестве альтернативы
ints = [8, 8, 8, 23, 45, 12, 78]
inds = [tup for tup in enumerate(ints)]
если вы хотите получить как индекс, так и значение в ints
в виде списка кортежей.
Он использует метод enumerate
в выбранном ответе на этот вопрос, но со списком, что делает его быстрее с меньшим количеством кода.
Если бы я перебрал числа = [1,2,3,4,5] Я бы сделал
for i, num in enumerate(nums, start = 1):
print(i, num)
Или получите длину как l = len (nums)
for i, num in range(1, l + 1):
print(i, nums[i])
Это также можно сделать с помощью метода index()
for i in ints:
print(ints.index(i), i)
Здесь индексация начинается с 0. Но если вам нужно начать с 1, просто добавьте 1 к методу index()
следующим образом
for i in int:
print(int.index(i) + 1, i)
Чтобы напечатать кортеж (индекс, значение) в понимании списка, используя цикл for
:
ints = [8, 23, 45, 12, 78]
print [(i,ints[i]) for i in range(len(ints))]
Вывод:
[(0, 8), (1, 23), (2, 45), (3, 12), (4, 78)]
Вот что вы получаете, когда получаете доступ к индексу в циклах for
:
for i in enumerate(items): print(i)
for i, val in enumerate(items): print(i, val)
for i, val in enumerate(items): print(i)
Надеюсь, это поможет.
Вы получили несколько ответов, объясняющих enumerate
, но если вам нужен только индекс для доступа к соответствующим записям в двух списках, В Python 3 есть еще один способ, который будет чище и проще: zip
.
Например, если вы используете индекс для извлечения соответствующих имен для номеров в вашем списке, вы можете сделать это следующим образом:
ints = [8, 23, 45, 12, 78]
names = ["John", "Sue", "Johannes", "Patel", "Ian"]
for int, name = zip(ints, names):
print("{} - {}".format(name, int)
Это дало бы
8 - John
23 - Sue
45 - Johannes
12 - Patel
78 - Ian
Это служит цели достаточно хорошо:
list1 = [10, 'sumit', 43.21, 'kumar', '43', 'test', 3]
for x in list1:
print('index:', list1.index(x), 'value:', x)