for - while loop python




الوصول إلى الفهرس في حلقات "for"؟ (14)

كيف يمكنني الوصول إلى الفهرس نفسه للحصول على قائمة مثل ما يلي؟

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

عندما أتصفحها باستخدام حلقة for ، كيف يمكنني الوصول إلى فهرس الحلقة ، من 1 إلى 5 في هذه الحالة؟


باستخدام حلقة 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

أو في بعض الأحيان أكثر شيوعًا (ولكن بشكل غير منتظم) في بيثون:

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

استخدم دالة التعداد

تعمل دالة 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 عند صفر
  • للحصول على هذه الفهارس من متكرر كما تتكرر فوقه ، استخدم الدالة التعداد
  • باستخدام التعداد بالطريقة الاصطلاحية (مع تفريغ tuple) يخلق رمزًا أكثر قابلية للقراءة وصيانته:

لذلك افعل هذا:

for index, item in enumerate(items, start=0):   # Python indexes start at zero
    print(index, item)

أسرع طريقة للوصول إلى فهارس القائمة داخل حلقة في 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 هو الفائز.

إضافة بعض الروابط المفيدة أدناه:


أولاً ، ستكون الفهارس من 0 إلى 4. تبدأ لغات البرمجة العد من 0؛ لا تنسى ذلك وإلا ستواجه استثناء خارج نطاق الفهرس. كل ما تحتاجه في حلقة for هو متغير يتم حسابه من 0 إلى 4 مثل:

for x in range(0, 5):

ضع في اعتبارك أني كتبت من 0 إلى 5 لأن الحلقة توقف رقمًا واحدًا قبل الحد الأقصى. :)

للحصول على قيمة استخدام فهرس

list[index]

إذا كان لي أن أكرر nums = [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])

بالطريقة القديمة:

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

في سؤالك ، تكتب "كيف يمكنني الوصول إلى فهرس الحلقة ، من 1 إلى 5 في هذه الحالة؟"

ومع ذلك ، يتم تشغيل فهرس قائمة ، من صفر. لذا ، نحتاج إلى معرفة ما إذا كان ما تريده فعلاً هو الفهرس والعنصر لكل عنصر في قائمة ، أو ما إذا كنت تريد حقًا أن تبدأ الأرقام من 1. لحسن الحظ ، في بيثون من السهل القيام بأي من الأمرين أو كليهما.

أولاً ، لتوضيح ، الدالة التعداد ، تكرر الفهرس والعنصر المقابل لكل عنصر في قائمة.

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

هذا يقودنا إلى مفتاح بدء = n لتعداد (). هذا ببساطة يزيل الفهرس ، يمكنك ببساطة إضافة رقم إلى الفهرس داخل الحلقة.

for n,a in enumerate(alist,start=1):
    print( "%d %d"%(n,a) )

الذي الناتج

1 1
2 2
3 3
4 4
5 5

لا أعرف ما إذا كان ما يلي هو 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

لطباعة tuple من (index، value) في الفهم بالقائمة باستخدام حلقة 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)]

من البديهي أن تبدأ من 1 غير 0 :

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

ملحوظة

تلميح هام ، على الرغم من أن مضللة بعض الشيء حيث سيكون index tuple (idx, item) هنا. جاهز للمضي.


هذا يخدم الغرض جيدا بما فيه الكفاية:

list1 = [10, 'sumit', 43.21, 'kumar', '43', 'test', 3]
for x in list1:
    print('index:', list1.index(x), 'value:', x)

يعتبر استخدام متغير حالة إضافي ، مثل متغير فهرس (والذي عادة ما تستخدمه في لغات مثل C أو PHP) ، غير متوازن.

الخيار الأفضل هو استخدام enumerate() الدالة المضمنة enumerate() ، المتوفر في كل من Python 2 و 3:

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

تحقق من PEP 279 لأكثر من ذلك.


يمكنك أيضًا تجربة هذا:

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']

يمكنك القيام بذلك مع هذا الرمز:

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

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




list