程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python.迭代器對象iter()(基於iterator特性拆解繁復的單行“裝逼代碼”,搞明白序列定長元素選取“秘法”。)

編輯:Python

Python 官網 python 前沿。可惜是英文原版。所以,我要練習英文閱讀。🧐🧐" rel="noopener noreferrer">https://www.python.org/


  • Free:大咖免費“聖經”教程《 python 完全自學教程》,不僅僅是基礎那麼簡單……

  • My CSDN主頁、My HOT博、My Python 學習個人備忘錄
  • 好文力薦、 老齊教室

自學並不是什麼神秘的東西,一個人一輩子自學的時間總是比在學校學習的時間長,沒有老師的時候總是比有老師的時候多。
—— 華羅庚




內置函數iter()
(built-in function iter)


目 錄

  • 1、裝逼“單行”代碼,激起我“分拆”欲望
  • 2、iter(object)常規用法
  • 3、iter(object, sentinel)兩個參數用法
  • 4、zip()、map()返回對象就是iterator
  • 5、iter(object)配合zip()的“特殊”用法
    序列定長元素選取。
  • 6、iter()官方文檔

單行裝逼代碼

print(''.join(chr(int(''.join(i), 16)) for i in zip(*[iter('576f772c2049276d2077726974696e6720696e2068657861646563696d616c21')]*2)))

Run這行代碼,會輸出下面那句話。我感覺好神奇!決定Study……


Wow, I'm writing in hexadecimal!

仔細“研究”、拆分後,發現是zip()對同一個迭代器作用,產生的Magic(魔法)。這又讓我想要對iter()“鑽研”了一番。


回目錄

先看看iter()的“文檔”:

print(iter.__doc__)

iter(iterable) -> iterator
iter(callable, sentinel) -> iterator
Get an iterator from an object. In the first form, the argument must supply its own iterator, or be a sequence.
In the second form, the callable is called until it returns the sentinel.

“文檔”顯示:iter()有給定一個參數、給定兩個參數,兩種用法。

一、iter(iterable) -> iterator
當只給定一個參數時,參數必須是可迭代對象(iterable object),返回那個參數(iterable object)的iterator(迭代器)。換句話說,就是iter()賦予了iterable object能一個一個返回內容物(元素)的能力,就是讓iterable object具有了__next__()“魔法”方法。可以用內置函數next()實現,也可以用自身“新”得技能(next()方法)實現。iterable object參數可以是符合條件的“任意”Python對象。如:

/sdcard/qpython $ python
Python 3.10.2 (main, Mar 1 2022, 12:58:06) [Clang 12.0.8 (https://android.googlesource.com/toolchain/llvm-project c935d99d7 on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> iter('ok')
<str_iterator object at 0x79d5ca4460>
>>> iter([3, 4])
<list_iterator object at 0x79d5c21c90>
>>> iter((6, 'c'))
<tuple_iterator object at 0x79d5c5aa70>
>>> iter({
3,9})
<set_iterator object at 0x79d5ca3a80>
>>> iter({
5: 6, 'ok': 'haha'})
<dict_keyiterator object at 0x79d5c36700>
>>>>

如您所見,各種對象返回的迭代器,都留著各自的“烙印”。字符串、列表、元組、集合、字典key,這Python五大基礎類型,都帶著各自的印記。這對“她”作為迭代器使用,毫無阻滯。下面就來煉煉:

>>> iter('ok').__next__()
'o'
>>> iter([3, 4]).__next__()
3
>>> iter((6, 'c')).__next__()
6
>>> iter(('c', 9)).__next__()
'c'
>>> iter({
3, 9}).__next__()
9
>>> d = iter({
5: 6, 'ok': 'haha'})
>>> d.__next__()
5
>>> d.__next__()
'ok'
>>>

一個一個迭代器,可以變著花樣使。

Python3.x內置函數zip()、map()返回的就是iterator。如:

>>> z = zip((4, 6), list('Good'))
>>> z
<zip object at 0x78cffa1380>
>>> z.__next__()
(4, 'G')
>>> z.__next__()
(6, 'o')
>>> z.__next__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> m = map(str, range(6, 9))
>>> m
<map object at 0x78cff99de0>
>>> next(m, 'The end.')
'6'
>>> next(m, 'The end.')
'7'
>>> next(m, 'The end.')
'8'
>>> next(m, 'The end.')
'The end.'
>>>

由前面“操作”可以看出,zip object、map object她就是iterator,她們有__next__()方法,內置函數next()也可以調用。

>>> next(zip((4,), ['d']))
(4, 'd')
>>> map(int, list('456')).__next__()
4

回目錄

iter(object)配合zip()的“特殊”用法

iter()借助zip()和*星號“聯眾”之力,可以實現用簡潔的代碼完成序列定長選取。例:

為簡化例子,先定義了個函數mychoice(iterator, num)。

>>> def mychoice(iterator, num):
... ''' iterator -> 迭代器對象 ... num -> int,連續取值數量 '''
... return zip(*[iterator]*num)
...
>>> print(*mychoice(iter(range(9)), 2))
(0, 1) (2, 3) (4, 5) (6, 7)
>>> print(*mychoice(iter('Chongqing'), 3))
('C', 'h', 'o') ('n', 'g', 'q') ('i', 'n', 'g')
>>>

神不神奇,驚不驚喜。這,就是本筆記開篇提到的“裝逼代碼”的“奇妙”用法。您也許已經發現,由於zip()的特性,不能完全匹配成組的序列元素,被捨棄。比如還原十六進制編碼的字符,四位或者兩位都是沒有余數的,所以對“實際”的應用,幾乎沒有影響。這,是如何實現的哩?我想是基於迭代器“只可以讀取一次”的特性,在iter()官方文檔沒有找到相關說明。因為我在這裡zip()的參數,都是同一個迭代器,重復幾次迭代器就是實現連續取幾個序列元素。

上面的return 語句,也可以寫成

return zip(iterator, ierator, ...) # 想連續取幾個序列元素就重復幾次。

舉個粟子:

>>>
>>> iterator = iter('I love you.')
>>> tem = iterator
>>> print(*zip(tem, tem, tem))
('I', ' ', 'l') ('o', 'v', 'e') (' ', 'y', 'o')
>>>

對同一個迭代器,在zip()參數中重復三次,就完成了連續三個字符的選取。

利用這一“特性”,可以“異想天開”的做些事情。例如:把十六進制字符編碼還原成“本來的樣子”。

s = '我是重慶“夢幻精靈_cq”,我愛Python,is studying 一條十六進制碼搞怪語句。'
en = "Wow, I'm writing in hexadecimal!"
hex_s = '576F772C2049276D2077726974696E6720696E2068657861646563696D616C21'
def to_hex(s, num=2):
''' 將字符轉換成十六進制編碼,\n字符含中文num=4,\n默認純英文。 '''
return ''.join(map(lambda x: hex(ord(x))[2:].upper().zfill(num), s)) # 轉換字符編碼並去除十六進制標識字符用設置位數存儲,不足位補“0”。無縫拼接字符,返回字符串。
if __name__== '__main__':
print(f"\n原字符串:{
s}\n十六進制:\n{
to_hex(s, 4)}") # 用四位十六進制字符保存字符編碼。
print(f"\n原字符串:{
en}\n十六進制:\n{
to_hex(en)}") # 用to_hex()默認參數轉換英文字符成2位十六進制ASCII編碼。
b = zip(*[iter(to_hex(s, 4))]*4) # 轉換字符成十六進制字符編碼。
print(f"\n十六進制編碼字符串:\n{
[''.join(i) for i in b]}\n") # 打印十六進制字符編碼字符串。
b = zip(*[iter(to_hex(s, 4))]*4) # 轉換字符成十六進制字符編碼。
for i in b: # 遍歷還原字符。
print(chr(int(''.join(i), 16)), end="")

輸出截屏圖片

在對迭代器變量b的操作中,為什麼會對其兩次賦值。因為b在打印十六進制字符編碼列表時,已讀取b所以再對b操作得先賦值。(iterator只可以讀取一次。)

也可見只用一條復合語句完成還原,或者轉換 -> 還原整個過程。不過,“較長”的復合語句“生澀難讀”,除了“裝逼”,少用為宜。

print(f"\n\n{
''.join([chr(int(''.join(i), 16)) for i in zip(*[iter(hex_s)]*2)])}")
print(f"\n{
''.join(map(lambda x: chr(int(''.join(x),16)), zip(*[iter(to_hex(s,4))]*4)))}\n")

輸出截屏圖片


回目錄

二、iter(iterable, sentinel) -> iterator
如果給出第二參數sentinel,第一個參數必須是可調用對象(不帶參數的函數或者類方法,且每次調用會返回一個值),循環調用第一個參數,直到==第二參數(sentinel的值)。正如sentinel的釋義一樣,就是——“哨兵”——到此為止。不返回sentinel的值。如:

or more information.
>>> lis = range(9)
>>> iterator = iter(lis)
>>> tem = iter(iterator.__next__, 7)
>>> tem
<callable_iterator object at 0x78d0163940>
>>> print(*tem)
0 1 2 3 4 5 6
>>>
>>> iterator = iter('I am Dream elf, I live in Chongqing.')
>>> print(iter(iterator.__next__, ','))
<callable_iterator object at 0x78d01638b0>
>>> print(*iter(iterator.__next__, ','))
I a m D r e a m e l f

當第二參數sentinel是7時,就輸出她前面的0~6,不輸出7;當sentinel是“,”,就輸出前半句字符串,不帶輸出“,”。


回目錄

iter()官方文檔:
文檔鏈接https://docs.python.org/3/library/functions.html#iter

文檔內容,
iter(object[, sentinel])
Return an iterator object. The first argument(參數) is interpreted very differently depending on the presence of the second argument. Without a second argument, object must be a collection object which supports the iterable protocol (the iter() method), or it must support the sequence protocol (the getitem() method with integer arguments starting at 0). If it does not support either of those protocols, TypeError is raised. If the second argument, sentinel, is given, then object must be a callable object. The iterator created in this case will call object with no arguments for each call to its next() method; if the value returned is equal to sentinel, StopIteration will be raised, otherwise the value will be returned.

See also Iterator Types.

One useful application of the second form of iter() is to build a block-reader. For example, reading fixed-width blocks from a binary database file until the end of file is reached:

from functools import partial
with open(‘mydata.db’, ‘rb’) as f:
for block in iter(partial(f.read, 64), b’'):
process_block(block)


參考CSDN博文:

  • 《iter()的高階用法》
  • 《深入分析iter()》,文中有對iter()官方文檔的解讀。


回首頁

__上一篇:__ 根據給定字符數和字符,打印輸出“沙漏”和剩余數

__下一篇:__

我的HOT博:

  • Hot:pandas 數據類型之 Series(1026閱讀)
  • 聊天消息敏感詞屏蔽系統(字符串替換 str.replace(str1, *) )(1045閱讀)
  • 練習:銀行復利計算(用 for 循環解一道初中小題)(1097閱讀)
  • pandas 數據類型之 DataFrame(1577閱讀)
  • Hot:班裡有人和我同生日難嗎?(蒙特卡洛隨機模擬法)(2118閱讀)
  • Python字符串居中顯示(1659閱讀)
  • 練習:求偶數和、阈值分割和求差( list 對象的兩個基礎小題)(1658閱讀)
  • 用 pandas 解一道小題(1983閱讀)
  • 可迭代對象和四個函數(1075閱讀)
  • “快樂數”判斷(1236閱讀)
  • 羅馬數字轉換器(構造元素取模)(1955閱讀)
  • Hot:羅馬數字(轉換器|羅生成器)(4090閱讀)
  • Hot:讓QQ群昵稱色變的代碼(30925閱讀)
  • Hot:斐波那契數列(遞歸| for )(4054閱讀)
  • 柱狀圖中最大矩形(1659閱讀)
  • 排序數組元素的重復起止(1249閱讀)
  • 電話撥號鍵盤字母組合(1363閱讀)
  • 密碼強度檢測器(1839閱讀)
  • 求列表平衡點(1825閱讀)
  • Hot: 字符串統計(4295閱讀)
  • Hot:尼姆游戲(聰明版首發)(3446閱讀)尼姆游戲(優化版)(1057閱讀)
推薦條件點閱破千

回目錄


精品文章:

  • 好文力薦:《python 完全自學教程》齊偉書稿免費連載
  • OPP三大特性:封裝中的property
  • 通過內置對象理解python'
  • 正則表達式
  • python中“*”的作用
  • Python 完全自學手冊
  • 海象運算符
  • Python中的 `!=`與`is not`不同
  • 學習編程的正確方法

來源:老齊教室


回目錄

Python 入門指南【Python 3.6.3】


好文力薦:

  • 全棧領域優質創作者——寒佬(還是國內某高校學生)好文:《非技術文—關於英語和如何正確的提問》,“英語”和“會提問”是學習的兩大利器。

  • 【8大編程語言的適用領域】先別著急選語言學編程,先看它們能干嘛

  • 靠譜程序員的好習慣


CSDN實用技巧博文:

  • 8個好用到爆的Python實用技巧
  • python忽略警告
  • Python代碼編寫規范
  • Python的docstring規范(說明文檔的規范寫法)


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved