python基础-内置函数2-range zip enumerate iter aiter all filter next anext any slice all any filter map

1、迭代器、异步迭代器、枚举

range()

class range(stop)
class range(start, stop, step=1)

虽然被称为函数,但 range 实际上是一个不可变的序列类型,返回一个range对象。
range 构造器的参数必须为整数(可以是内置的 int 或任何实现了 __index__() 特殊方法的对象)。

  • 如果省略 step 参数,则默认为 1
  • 如果省略 start 参数,则默认为 0
  • 如果 step,则会引发 ValueError
  • 如果 step 为正值,确定 range r 内容的公式为 r[i] = start + step*i 其中 i >= 0r[i] < stop
  • 如果 step 为负值,确定 range 内容的公式仍然为 r[i] = start + step*i,但限制条件改为 i >= 0r[i] > stop
  • 如果 r[0] 不符合值的限制条件,则该 range 对象为空。 range 对象确实支持负索引,但是会将其解读为从正索引所确定的序列的末尾开始索引。
  • 元素绝对值大于 sys.maxsizerange 对象是被允许的,但某些特性 (例如 len()) 可能引发 OverflowError
>>> range(10)
range(0, 10)
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(10, -1, -1))
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
# 不满足参数使用规则时返回空元素的range对象
>>> list(range(0, 10, -1))
[]
>>> list(range(0, 10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 我们常常拿range对象作为迭代次数限制或者作为序列类型的索引
>>> for i in range(10):
...     print(i)
0
1
2
...省略
>>> nums = [1,2,3,4,5,6,7,8,9]
>>> for i in range(len(nums)):
...     print(nums[i])
1
2
3
...省略

zip()

zip(*iterables, strict=False)

在多个迭代器上并行迭代,从每个迭代器返回一个数据项组成元组,返回值为一个zip对象。

  • 默认情况下,zip()最短的迭代完成后停止。较长可迭代对象中的剩余项将被忽略,结果会裁切至最短可迭代对象的长度
  • 如果只希望 zip() 用于可迭代对象等长的情况下。这时建议用 strict=True 的选项。这将一个可迭代对象在其他几个之前被耗尽则会引发 ValueError
  • zip()* 运算符相结合可以用来拆解一个列表
for item in zip([1, 2, 3], ['sugar', 'spice', 'everything nice']):
...     print(item)
...
(1, 'sugar')
(2, 'spice')
(3, 'everything nice')
# zip可以直接被解包赋值
>>> x1,x2,x3 = zip([1,2,3],[4,5,6])
>>> x1
(1, 4)
>>> x2
(2, 5)
>>> x3
(3, 6)
# *zip()拆解
>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> x2, y2 = zip(*zip(x, y)) # 相当于zip((1,4),(2,5),(3,6)), x2与y2是元组类型
>>> x == list(x2) and y == list(y2)
True
# 用于生成字典
>>> dict(zip([1, 2, 3], ['sugar', 'spice', 'everything nice']))
{1: 'sugar', 2: 'spice', 3: 'everything nice'}
# 截断
>>> list(zip([1,2,3],[4,5,6,7,8,9]))
[(1, 4), (2, 5), (3, 6)]

enumerate()

enumerate(iterable, start=0)

返回一个枚举对象。iterable 必须是一个序列,或 iterator,或其他支持迭代的对象。 enumerate() 返回的迭代器的 __next__() 方法返回一个元组,里面包含一个计数值(从 start 开始,默认为 0)和通过迭代 iterable 获得的值。

>>> seasons = ['Spring', 'Summer', 'Fall', 'Winter']
>>> list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
>>> [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
>>> list(enumerate(seasons, start=1))
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
>>> [(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
# enumerate等价于
def enumerate(iterable, start=0):
    n = start
    for elem in iterable:
        yield n, elem
        n += 1

iter()

iter(object)
iter(object, sentinel)

返回一个iterator对象。 根据是否存在第二个参数,对第一个参数的解读会有很大的不同。
如果没有第二个参数,object 必须是一个支持 iterable 协议 (有 __iter__() 方法) 的多项集对象,或者必须支持序列协议 (有 __getitem__() 方法并使用从0开始的整数参数)。 如果它不支持这些协议,则会引发 TypeError
如果给出了第二个参数 sentinel,则 object 必须是一个可调用对象(callable)。 在这种情况下创建的迭代器将针对每次调用其 __next__() 方法不带参数地调用 object;如果返回的值等于 sentinel,则会引发 StopIteration,否则将返回该值。
如果使用iter(iterable)迭代一个可迭代对象显得比较多余,因为iterable本身就可以直接迭代,但是iter有以下两点主要用途

  • 控制配合next()控制迭代过程
  • 使用sentinel进行打断
>>> iter_ele = iter([1,2,3])
>>> next(iter_ele)
1
>>> next(iter_ele)
2
>>> next(iter_ele)
3
>>> next(iter_ele)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> def get_input():
...     return input("Enter something (or 'STOP' to end): ")
...
>>> # 创建迭代器,直到用户输入 'STOP'
... for user_input in iter(get_input, 'STOP'):
...     print(f'You entered: {user_input}')
...
Enter something (or 'STOP' to end): 1
You entered: 1
Enter something (or 'STOP' to end): 2
You entered: 2
Enter something (or 'STOP' to end): 3
You entered: 3
Enter something (or 'STOP' to end): 4
You entered: 4
Enter something (or 'STOP' to end): STOP
# 在一些复杂的场景加也可以自定义迭代过程
>>> def get_next_value():
...     values = [3, 2, 1, 0, -1, -2]
...     for value in values:
...         yield value
>>> # 创建生成器
... value_generator = get_next_value()
>>>
>>> # 定义一个可调用对象来获取下一个值
... def next_value():
...     return next(value_generator)
>>> # 使用可调用对象和哨兵值创建迭代器
... my_iter = iter(next_value, 0)
>>>
>>> # 使用迭代器遍历
... for item in my_iter:
...     print(item)
...
3
2
1

aiter()

aiter(async_iterable)

返回 asynchronous iterableasynchronous iterator 。相当于调用 x.__aiter__()

在python 3.10.才开始添加

>>> import asyncio
# 使用next()迭代
>>> async def async_generator():
...     yield 1
...     await asyncio.sleep(1)  # 模拟异步操作
...     yield 2
...     await asyncio.sleep(1)  # 模拟异步操作
...     yield 3
...
>>> async def main():
...     async_iterable = async_generator()
...     async_iterator = aiter(async_iterable)
...     while True:
...         try:
...             value = await anext(async_iterator)
...             print(value)
...         except StopAsyncIteration:
...             break
...
>>> asyncio.run(main())
1
2
3
# 使用for in 迭代
>>> async def async_gen():
...     for i in range(3):
...         await asyncio.sleep(1)
...         yield i
...
>>> async def main():
...     async for item in aiter(async_gen()):
...         print(item)
...
>>> asyncio.run(main())
0
1
2

next()

next(iterator)
next(iterator, default)

通过调用 iterator__next__() 方法获取下一个元素。如果迭代器耗尽,则返回给定的 default,如果没有默认值则触发 StopIteration

>>> # 使用 next() 函数遍历迭代器
... my_iter = iter([1, 2, 3])
... while True:
...     try:
...         # 获取下一个元素
...         element = next(my_iter)
...         print(element)
...     except StopIteration:
...         # 没有更多元素,退出循环
...         print("Iteration complete.")
...         break
1
2
3
Iteration complete.
# 使用 next() 函数手动控制迭代
>>> my_iter = iter([1, 2, 3, 4, 5])
>>> next(my_iter)
1
>>> next(my_iter)
2
>>> next(my_iter)
3
# 使用 `next()` 函数获取下一个元素,并设置默认值
>>> my_iter = iter([1, 2, 3])
>>> print(next(my_iter, 0))  
1
>>> print(next(my_iter, 0))  
2
>>> print(next(my_iter, 0)) 
3
>>> print(next(my_iter, 0)) 
0

anext()

awaitable anext(async_iterator)
awaitable anext(async_iterator, default)

当进入 await 状态时,从给定 asynchronous iterator 返回下一数据项,迭代完毕则返回 default
这是内置函数 next() 的异步版本,类似于:
调用 async_iterator__anext__() 方法,返回一个 awaitable。等待返回迭代器的下一个值。若有给出 default,则在迭代完毕后会返回给出的值,否则会触发 StopAsyncIteration

在python 3.10.才开始添加

>>> import asyncio
>>> async def async_gen():
...     for i in range(3):
...         await asyncio.sleep(1)
...         yield i
>>> async def main():
...     agen = async_gen()
...     print(await anext(agen, 'default')) 
...     print(await anext(agen, 'default')) 
...     print(await anext(agen, 'default')) 
...     print(await anext(agen, 'default')) 
...     print(await anext(agen, 'default')) 
>>> asyncio.run(main())
0
1
2
default
default

2具有固定功能的简化迭代

all()

all(iterable)

如果 iterable 的所有元素均为真值(或可迭代对象为空)则返回 True 。等价于:

def all(iterable):
    for element in iterable:
        if not element:
            return False
    return True
>>> all([1,2,3])
True
>>> all([1,2,3,0])
False
>>> all([1,2,3,""])
False
>>> all(i > 3 for i in [1,2,3,4])
False
>>> all(i.isalpha() for i in "ALPHA1")
False

any()

如果 iterable 的任一元素为真值则返回 True。 如果可迭代对象为空,返回 False。 等价于:

def any(iterable):
    for element in iterable:
        if element:
            return True
    return False
>>> any([0,"",{},set(),None,0.0,False])
False
>>> any([0,"",{},set(),None,0.0,False,1])
True

filter()

filter(function, iterable)

使用 iterable function 返回真值的元素构造一个迭代器。 iterable 可以是一个序列,一个支持迭代的容器或者一个迭代器。 如果 functionNone,则会使用标识号函数,也就是说,iterable 中所有具有假值的元素都将被移除。
请注意, filter(function, iterable) 相当于一个生成器表达式,当 function 不是 None 的时候为 (item for item in iterable if function(item))functionNone 的时候为 (item for item in iterable if item)

# 过滤掉奇数
>>> filter(lambda x: x % 2 == 0, range(10))
<filter object at 0x000001B7AD2FB128>
>>> list(filter(lambda x: x % 2 == 0, range(10)))
[0, 2, 4, 6, 8]
# 过滤空字符串
>>> list(filter(lambda x: x, ["hello", "", "world", " ", "python", ""]))
['hello', 'world', ' ', 'python']
# 过滤空字符串和空格字符串
>>> list(filter(lambda x: x.strip(), ["hello", "", "world", " ", "python", ""]))
['hello', 'world', 'python']

map()

map(function, iterable, *iterables)

返回一个将 function 应用于 iterable 的每一项,并产生其结果的迭代器。 如果传入了额外的 iterables 参数,则 function 必须接受相同个数的参数并被用于到从所有可迭代对象中并行获取的项。 当有多个可迭代对象时,当最短的可迭代对象耗尽则整个迭代将会停止。

>>> map(lambda x: x**2, [1,2,3,4])
<map object at 0x000001B7AF063320>
>>> list(map(lambda x: x**2, [1,2,3,4]))
[1, 4, 9, 16]
>>> list(map(lambda x: int(x), [1,2,'3']))
[1, 2, 3]
>>> list(map(sorted, [[3, 1, 2], [9, 7, 8], [6, 5, 4]]))
[[1, 2, 3], [7, 8, 9], [4, 5, 6]]
>>> list(map(max, [[3, 1, 2], [9, 7, 8], [6, 5, 4]]))
[3, 9, 6]

slice()

class slice(stop)
class slice(start, stop, step=None)

返回一个表示由 range(start, stop, step) 指定的索引集的 slice 对象。 startstep 参数默认为 None

>>> [1, 2, 3, 4, 5][slice(1,4)]
[2, 3, 4]
>>> [1, 2, 3, 4, 5][slice(1,4,2)]
[2, 4]
>>> "Hello, World!"[slice(1,6,2)]
'el,'
>>> "Hello, World!"[1:6:2]
'el,'
>>> slice(1, None, 2)
slice(1, None, 2)
>>> [1,2,3,4,5][slice(1, None, 2)]
[2, 4]

reversed()

返回一个反向的新的 iteratorseq 必须是一个具有 __reversed__() 方法或是支持序列协议(具有 __len__() 方法和从 0 开始的整数参数的 __getitem__() 方法)的对象。

>>> reversed([1,2,3,4,5])
<list_reverseiterator object at 0x000001B79D72ACC0>
>>> list(reversed([1,2,3,4,5]))
[5, 4, 3, 2, 1]
# 自定义一个调换奇偶顺序
>>> class MyCustomSequence:
...     def __init__(self, data):
...         self.data = data
...     def __len__(self):
...         return len(self.data)
...     def __getitem__(self, index):
...         return self.data[index]
...     def __reversed__(self):
...         return self.data[0::2] + self.data[1::2]
>>> data = MyCustomSequence([1,2,3,4,5])
>>> reversed(data)
[1, 3, 5, 2, 4]

sorted()

sorted(iterable, /, *, key=None, reverse=False)

根据 iterable 中的项返回一个新的已排序列表。

  • 具有两个可选参数,它们都必须指定为关键字参数。
>>> sorted([4,3,5,6])
[3, 4, 5, 6]
  • key 指定带有单个参数的函数,用于从 iterable 的每个元素中提取用于比较的键 (例如 key=str.lower)。 默认值为 None (直接比较元素)。
>>> sorted(['banana', 'cherry', 'apple'], key=len)
['apple', 'banana', 'cherry']
  • reverse 为一个布尔值。 如果设为 True,则每个列表元素将按反向顺序比较进行排序。
>>> sorted(['apple', 'banana', 'cherry'], key=len, reverse=True)
['banana', 'cherry', 'apple']
  • 使用 functools.cmp_to_key() 可将老式的 cmp 函数转换为 key 函数。cmp的返回值必须是0,1,-1,分别表示相等、大于、小于
>>> from functools import cmp_to_key
>>> def compare(a, b):
...     return (a > b) - (a < b) # 0,1,-1
>>> sorted(['apple', 'banana', 'cherry'], key=cmp_to_key(compare))
['apple', 'banana', 'cherry']
  • 内置的 sorted() 确保是稳定的。 如果一个排序确保不会改变比较结果相等的元素的相对顺序就称其为稳定的 — 这有利于进行多重排序(例如先按部门、再按薪级排序)。
>>> sorted([('apple', 2), ('banana', 1), ('cherry', 2)], key=lambda x: x[1])
[('banana', 1), ('apple', 2), ('cherry', 2)]
  • 排序算法只使用 < 在项目之间比较。 虽然定义一个 __lt__() 方法就足以进行排序,但 PEP 8 建议实现所有六个 富比较 。 这将有助于避免在与其他排序工具(如 max() )使用相同的数据时出现错误,这些工具依赖于不同的底层方法。实现所有六个比较也有助于避免混合类型比较的混乱,因为混合类型比较可以调用反射到 __gt__() 的方法
>>> class MyClass:
...     def __init__(self, value):
...         self.value = value
...
...     def __lt__(self, other):
...         return self.value < other.value
...
...     def __eq__(self, other):
...         return self.value == other.value
>>> sorted([MyClass(3), MyClass(1), MyClass(2)])
[<__main__.MyClass object at 0x000001B79D730828>, <__main__.MyClass object at 0x000001B79D7309B0>, <__main__.MyClass object at 0x000001B79D730978>]
>>> [i.value for i in sorted([MyClass(3), MyClass(1), MyClass(2)])]
[1, 2, 3]

字典排序

# 按键排序
>>> dict(sorted(my_dict.items()))
{'apple': 2, 'banana': 3, 'cherry': 1}
# 按值排序
>>> dict(sorted(my_dict.items(), key = lambda x:x[1]))
{'cherry': 1, 'apple': 2, 'banana': 3}

sum()

sum(iterable, /, start=0)

start 开始(这里的start是说以start为初始值,然后一直从iterable[0]+...+iterable[len(iterable)-1],请注意并不是从iterable[start]+...+iterable[len(iterable)-1]),自左向右对 iterable 的项求和并返回总计值。 iterable 的项通常为数字,而 start 值则不允许为字符串。

在 3.8 版本发生变更: start 形参可用关键字参数形式来指定。
在 3.12 版本发生变更: 对浮点数求和的算法已更改为一种在大多数构建中提供更高精度的算法

>>> sum([1,2,3])
6
>>> sum([1,2,3], 1)
7
# 3.8变笨前并没有start形参
>>> sum([1,2,3], start = 1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sum() takes no keyword arguments
# 3.8版本之后
>>> sum([1,2,3], start=1)
7

max()

max(iterable, *, key=None)
max(iterable, *, default, key=None)
max(arg1, arg2, *args, key=None)

返回可迭代对象中最大的元素,或者返回两个及以上实参中最大的。
如果只提供了一个位置参数,它必须是非空 iterable,返回可迭代对象中最大的元素;如果提供了两个及以上的位置参数,则返回最大的位置参数。
有两个可选只能用关键字的实参。key 实参指定排序函数用的参数,如传给 list.sort() 的。default 实参是当可迭代对象为空时返回的值。如果可迭代对象为空,并且没有给 default ,则会触发 ValueError
如果有多个最大元素,则此函数将返回第一个找到的。这和其他稳定排序工具如 sorted(iterable, key=keyfunc, reverse=True)[0] heapq.nlargest(1, iterable, key=keyfunc) 保持一致。

在 3.4 版本发生变更: 增加了 default 仅限关键字形参。
在 3.8 版本发生变更: key 可以为 None。

>>> max([6,3,2,5])
6
>>> max(6,3,2,5)
6
# 根据元组索引1位置最大值
>>> max((1,2),(2,5),(5,1), key=lambda x:x[1])
(2, 5)
# 直接对字典求max得到键的max
>>> max({"a":3,"c":4,"b":1})
'c'
# 得到key最大的key-val
>>> max({"a":3,"c":4,"b":1}.items())
('c', 4)
# 得到val最大的key-val
>>> max({"a":3,"c":4,"b":1}.items(), key=lambda x:x[1])
('c', 4)
# 空sequence会使用默认值
>>> max([],default=0)
0
# 空sequence没有默认值时会报错
>>> max([])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: max() arg is an empty sequence

min()

min(iterable, *, key=None)
min(iterable, *, default, key=None)
min(arg1, arg2, *args, key=None)

返回可迭代对象中最小的元素,或者返回两个及以上实参中最小的。
min()max()功能相反,使用形式相同

在 3.4 版本发生变更: 增加了 default 仅限关键字形参。
在 3.8 版本发生变更: key 可以为 None。

>>> min([6,3,2,5])
2
>>> min(6,3,2,5)
2
# 根据元组索引1位置最小值
>>> min((1,2),(2,5),(5,1), key=lambda x:x[1])
(5, 1)
# 直接对字典求min得到键的min
>>> min({"a":3,"c":4,"b":1})
'a'
# 得到key最小的key-val
>>> min({"a":3,"c":4,"b":1}.items())
('a', 3)
# 得到val最小的key-val
>>> min({"a":3,"c":4,"b":1}.items(), key=lambda x:x[1])
('b', 1)
# 空sequence会使用默认值
>>> min([],default=0)
0
# 空sequence没有默认值时会报错
>>> min([])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: min() arg is an empty sequence

len()

len(s)

返回对象的长度(元素个数)。实参可以是序列(如 stringbytestuplelistrange 等)或集合(如 dictionarysetfrozen set 等)。len 对于大于 sys.maxsize 的长度如 range(2 ** 100) 会引发 OverflowError
s不是基本类型时,会将len()转交给s.__len__()

>>> len([1,2,3,4])
4

>>> class MyCustomClass:
...     def __init__(self, data):
...         self.data = data
...     def __len__(self):
...         return len(self.data)
...
>>> my_object = MyCustomClass([1, 2, 3, 4, 5])
>>> len(my_object)
5
  • 36
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值