Питання Доступ до індексу в "для" циклі?


Як отримати доступ до самого індексу для такого списку?

ints = [8, 23, 45, 12, 78]

Коли я петлю через неї, використовуючи for цикл, як я можу отримати доступ до індексу циклу, від 1 до 5 у цьому випадку?


2563
2018-02-06 22:47


походження




Відповіді:


Використання додаткової переміни стану, наприклад індексної змінної (яку ви зазвичай використовуєте в таких мовах, як C або PHP) вважається непітонічною.

Кращим варіантом є використання вбудованої функції enumerate(), доступний як в Python 2, так і в 3:

for idx, val in enumerate(ints):
    print(idx, val)

Перевірити PEP 279 для більш.


4456
2018-02-06 22:52



Як зазначає Аарон нижче, використовуйте start = 1, якщо ви хочете отримати 1-5 замість 0-4. - clozach


Використовуючи для циклу, як я можу отримати доступ до індексу циклу, від 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)

Уніфікований контроль потоку

Те, що ви просите, є пітонічним еквівалентом наступного, який є алгоритмом, який більшість програмістів мов нижчого рівня використовуватимуть:

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

Або на мовах, у яких немає циклу для кожного циклу:

index = 0
while index < len(items):
    print(index, items[index])
    index += 1

або іноді частіше (але унідіоматично), знайдені в Python:

for index in range(len(items)):
    print(index, items[index])

Використовуйте функцію перерахування

Python's enumerate функція зменшує візуальний безлад, приховуючи облік показників, і інкапсулюючи ітерабельний в інший ітерабельний ( 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)

519
2018-01-21 17:11





Це дуже просто почати з 1 окрім 0:

for index, item in enumerate(iterable, start=1):
   print index, item

Примітка

Важливий натяк, хоч і трохи оманливий з тих пір index буде а tuple  (idx, item) тут Можеш йти.


105
2018-05-27 10:04



Питання було про список індексів; оскільки вони починаються з 0, то починати з іншого номера немає сенсу, тому що індекси були б неправильними (так, ОП також зазначив, що це неправильно). В іншому випадку, викликати змінну, яка належить до index, item просто index Дуже вводить в оману, як ви помітили. Просто використовуй for index, item in enumerate(ints). - Antti Haapala
Краще індексувати пари в скобках як (index), він буде працювати як на версіях Python 2 та 3. - hygull


for i in range(len(ints)):
   print i, ints[i]

67
2018-02-06 22:49



Це, мабуть, повинно бути xrange для попереднього 3.0. - Ben Blank
Ні, якщо швидкість не потрібна, не слід оптимізувати. - Georg Schölly
Не треба передчасно оптимізувати, хоча я погоджуюсь у цьому випадку через те, що в роботі 2.x і 3.x працюють однакові коди.
Використовуйте перерахування замість - saulspatz
Для Python 2.3 вище, використовуйте вбудовану функцію переліку, оскільки вона більше Pythonic. - januarvs


Оскільки є нормою в Python, існує кілька способів зробити це. У всіх прикладах припускаємо: lst = [1, 2, 3, 4, 5]

1. Використовуючи перерахування (вважається найбільш ідіоматичним)

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 з для. Він обробляє вкладені цикли краще, ніж інші приклади.


34
2017-08-15 02:17



У пункті 2 доступ до .index() має лінійну складність, що означає, що складність вашого циклу тепер є квадратичною. Крім того, це не працює, коли ваш список містить кілька рівних елементів, оскільки він завжди повертає індекс першого. - Aristide
@Charitoo Я видаляю пункт 2, тому що його ніколи не слід використовувати - jamylak
Чи можете ви одночасно мати кілька переліків? Скажімо, я хочу, щоб I та J були такими індексами, що J> I і т. Д.? Я вважаю, що для цього було б краще 3 - arviman


Старомодний шлях:

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)
>>> 

20
2018-02-06 22:52



Це ні неправильно і використовується в C / C ++ та інших. Це вважається непітонічним, але також може використовуватися в python. Подібно простим рішенням, яке розбиває його до джерела: + - Valor Naram
Де це говорить, що це неправильно? - Charlie Martin
Деякий пітон екстремісти скажемо, не робіть цього. Але я сказав це лише для того, щоб вказати, що існує декілька можливих шляхів - Valor Naram


Найшвидший спосіб отримати доступ до індексу списку в циклі 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 є переможцем.

Додайте кілька корисних посилань нижче:


16
2017-08-04 09:49



"читання підрахунків". Різниця швидкості у малій діапазоні <1000 є незначною. Це на 3% повільніше за вже невелику метрику часу. - Surest Texas


Я не знаю, чи є наступний 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

16
2017-10-28 18:17





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]) тому буде створено суб-список для цього елемента.


15
2018-02-05 17:28





Перш за все, показники будуть від 0 до 4. Мови програмування починають підраховуватися з 0; не забувайте про це, або ви зіткнетесь із винятком індексу. Все, що вам потрібно для циклу для циклу - це змінна, яка підраховує від 0 до 4 так:

for x in range(0, 5):

Майте на увазі, що я написав від 0 до 5, тому що цикл зупиняє один номер перед макс. :)

Щоб отримати значення використання індексу

list[index]

11
2018-05-25 15:08





Відповідно до цієї дискусії: http://bytes.com/topic/python/answers/464012-objects-list-index

Ітерація лічильника циклів

Поточна ідіома для циклічності над показниками використовує вбудовану функцію "діапазон":

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

через http://www.python.org/dev/peps/pep-0212/


9
2018-05-05 07:10



Це не буде працювати для повторення через генератори. Просто використовуйте enumerate (). - Tadeck
Сьогодні поточна ідіома - перелік, а не діапазон дзвінків. - TankorSmash