Python.迭代器对象iter()(基于iterator特性拆解繁复的单行“装逼代码”,搞明白序列定长元素选取“秘法”。)


Python 官网: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 "", 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="")

输出截屏图片
Python.迭代器对象iter()(基于iterator特性拆解繁复的单行“装逼代码”,搞明白序列定长元素选取“秘法”。)_第1张图片
  在对迭代器变量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")

输出截屏图片
Python.迭代器对象iter()(基于iterator特性拆解繁复的单行“装逼代码”,搞明白序列定长元素选取“秘法”。)_第2张图片


回目录

二、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规范(说明文档的规范写法)

你可能感兴趣的:(练习,笔记,python)