======================== 4.10 åºåˆ—上索引值è¿ä»£ ======================== ---------- 问题 ---------- ä½ æƒ³åœ¨è¿ä»£ä¸€ä¸ªåºåˆ—çš„åŒæ—¶è·Ÿè¸ªæ£åœ¨è¢«å¤„ç†çš„å…ƒç´ ç´¢å¼•ã€‚ ---------- 解决方案 ---------- 内置的 ``enumerate()`` 函数å¯ä»¥å¾ˆå¥½çš„解决这个问题: .. code-block:: python >>> my_list = ['a', 'b', 'c'] >>> for idx, val in enumerate(my_list): ... print(idx, val) ... 0 a 1 b 2 c ä¸ºäº†æŒ‰ä¼ ç»Ÿè¡Œå·è¾“出(è¡Œå·ä»Ž1开始)ï¼Œä½ å¯ä»¥ä¼ 递一个开始å‚数: .. code-block:: python >>> my_list = ['a', 'b', 'c'] >>> for idx, val in enumerate(my_list, 1): ... print(idx, val) ... 1 a 2 b 3 c è¿™ç§æƒ…å†µåœ¨ä½ é历文件时想在错误消æ¯ä¸ä½¿ç”¨è¡Œå·å®šä½æ—¶å€™éžå¸¸æœ‰ç”¨ï¼š .. code-block:: python def parse_data(filename): with open(filename, 'rt') as f: for lineno, line in enumerate(f, 1): fields = line.split() try: count = int(fields[1]) ... except ValueError as e: print('Line {}: Parse error: {}'.format(lineno, e)) ``enumerate()`` 对于跟踪æŸäº›å€¼åœ¨åˆ—表ä¸å‡ºçŽ°çš„ä½ç½®æ˜¯å¾ˆæœ‰ç”¨çš„。 æ‰€ä»¥ï¼Œå¦‚æžœä½ æƒ³å°†ä¸€ä¸ªæ–‡ä»¶ä¸å‡ºçŽ°çš„å•è¯æ˜ 射到它出现的行å·ä¸ŠåŽ»ï¼Œå¯ä»¥å¾ˆå®¹æ˜“的利用 ``enumerate()`` æ¥å®Œæˆï¼š .. code-block:: python word_summary = defaultdict(list) with open('myfile.txt', 'r') as f: lines = f.readlines() for idx, line in enumerate(lines): # Create a list of words in current line words = [w.strip().lower() for w in line.split()] for word in words: word_summary[word].append(idx) å¦‚æžœä½ å¤„ç†å®Œæ–‡ä»¶åŽæ‰“å° ``word_summary`` ,会å‘现它是一个å—å…¸(准确æ¥è®²æ˜¯ä¸€ä¸ª ``defaultdict`` ), 对于æ¯ä¸ªå•è¯æœ‰ä¸€ä¸ª ``key`` ,æ¯ä¸ª ``key`` 对应的值是一个由这个å•è¯å‡ºçŽ°çš„è¡Œå·ç»„æˆçš„列表。 如果æŸä¸ªå•è¯åœ¨ä¸€è¡Œä¸å‡ºçŽ°è¿‡ä¸¤æ¬¡ï¼Œé‚£ä¹ˆè¿™ä¸ªè¡Œå·ä¹Ÿä¼šå‡ºçŽ°ä¸¤æ¬¡ï¼Œ åŒæ—¶ä¹Ÿå¯ä»¥ä½œä¸ºæ–‡æœ¬çš„一个简å•ç»Ÿè®¡ã€‚ ---------- 讨论 ---------- å½“ä½ æƒ³é¢å¤–定义一个计数å˜é‡çš„时候,使用 ``enumerate()`` å‡½æ•°ä¼šæ›´åŠ ç®€å•ã€‚ä½ å¯èƒ½ä¼šåƒä¸‹é¢è¿™æ ·å†™ä»£ç : .. code-block:: python lineno = 1 for line in f: # Process line ... lineno += 1 但是如果使用 ``enumerate()`` 函数æ¥ä»£æ›¿å°±æ˜¾å¾—æ›´åŠ ä¼˜é›…äº†ï¼š .. code-block:: python for lineno, line in enumerate(f): # Process line ... ``enumerate()`` 函数返回的是一个 ``enumerate`` 对象实例, 它是一个è¿ä»£å™¨ï¼Œè¿”回连ç»çš„包å«ä¸€ä¸ªè®¡æ•°å’Œä¸€ä¸ªå€¼çš„元组, 元组ä¸çš„å€¼é€šè¿‡åœ¨ä¼ å…¥åºåˆ—上调用 ``next()`` 返回。 还有一点å¯èƒ½å¹¶ä¸å¾ˆé‡è¦ï¼Œä½†æ˜¯ä¹Ÿå€¼å¾—注æ„, æœ‰æ—¶å€™å½“ä½ åœ¨ä¸€ä¸ªå·²ç»è§£åŽ‹åŽçš„元组åºåˆ—上使用 ``enumerate()`` 函数时很容易调入陷阱。 ä½ å¾—åƒä¸‹é¢æ£ç¡®çš„æ–¹å¼è¿™æ ·å†™ï¼š .. code-block:: python data = [ (1, 2), (3, 4), (5, 6), (7, 8) ] # Correct! for n, (x, y) in enumerate(data): ... # Error! for n, x, y in enumerate(data): ...