精华内容
下载资源
问答
  • 本身实现了迭代方法的对象称之为可迭代对象可迭代对象特点:支持每次返回自己所包含的一个成员的对象;对象实现了 __iter__ 方法:所有数据结构都是可迭代对象;for 循环要求对象必须是一个可迭代对象;用户自定义...

    本身实现了迭代方法的对象称之为可迭代对象,可迭代对象特点:

    支持每次返回自己所包含的一个成员的对象;

    对象实现了 __iter__ 方法:

    所有数据结构都是可迭代对象;

    for 循环要求对象必须是一个可迭代对象;

    用户自定义的一些包含了 __iter__() 或 __getitem__() 方法的类。

    它与一般的序列类型(list, tuple 等)有什么区别呢?它一次只返回一个数据项,占用更少的内存,但它需要记住当前的状态,以便返回下一数据项。

    迭代器

    迭代器(iterator)就是一种可迭代对象。所谓的 迭代器就是重复做一件事,它又称为游标(cursor),它是程序设计的软件设计模式,是一种可在容器物件(container,如列表等)上实现元素遍历的接口。迭代器是一种特殊的数据结构,在 python 中,它也是以对象的形式存在的。

    简单来说,在 python2 中存在 next 方法的可迭代对象是迭代器;而在 python3 中则变成了 __next__ 方法。因此迭代器同时具有 __iter__ 和 __next__ 这两种方法。

    通过 python 内置函数 iter 可以将一个可迭代对象转换成一个迭代器。为什么要将可迭代对象转换成迭代器呢?因为只有迭代器才能使用 python 内置函数 next。

    迭代器会保存一个指针,指向可迭代对象的当前元素。调用 next 函数的时候,会返回当前元素,并将指针指向下一个元素。当没有下一个元素的时候,它会抛出 StopIteration 异常。

    一个简单的迭代器用法:

    lst = [['m', 2, 4, 5], ['x', 3, 4, 5]]

    for x in lst:

    key = x[0]

    for v in x[1:]:

    print()

    for x in lst:

    it = iter(x)

    key = next(it)

    for v in it:

    print()

    复制代码

    使用第二种循环也就是迭代器会比第一种更有效率,因为切片将列表复制一份,占用的内存更多。

    for 循环对于可迭代对象首先会调用 iter 方法将之转换为迭代器,然后不断的调用 next 方法,直到抛出 StopIteration 异常。

    it = iter(itratable)

    while True:

    try:

    next(it)

    except StopIteration:

    return

    复制代码

    生成器

    生成器也是函数,函数中只要有 yield 关键字,那么它就是生成器函数,返回值为生成器。生成器存在 __iter__ 和 __next__ 这两种方法,因此它是一个迭代器。生成器应用非常广泛,官方的异步 IO 基本上都是基于 yield 做的。当我们在 async def 定义的函数中使用 yield,那么这个函数就被称为异步生成器。

    当我们调用生成器函数的时候,它会返回一个生成器对象,我们要使用一个变量去接受它,然后通过操作这个变量去操作生成器。生成器也是函数,函数都是从上到下执行,当执行到 yield 语句时,这个函数就停止了,并且会将此次的返回值返回。如果 yield 语句后没有任何值,那么它的返回值就是 None;如果有值,会将这个值返回给调用者。如果使用了生成器的 send 方法(下面会提到),那么返回值将是通过这个方法传递进去的值(前提是 yield 语句后没有任何值)。

    所有的这些特性让生成器看起来和协程非常相似:可以多次调用、有多个切入点、执行可以被暂停。唯一的区别是生成器函数无法控制 yield 之后应继续执行的位置,因为控制权在调用者的手中。

    对于一个没有调用结束的生成器,我们可以使用 close 方法将其关闭,可以将其写在 try 的 finally 语句中。

    当使用 yield from 时,它将提供的表达式视为子迭代器,该子迭代器生成的所有值直接传递给当前生成器函数的调用者。任何传递给 send() 的值和通过throw() 传入的异常都会传递给基础迭代器(如果它有适当的方法去接收)。如果不是这种情况,那么 send() 会引发 AttributeError 或 TypeError,而 throw() 会立即引发传入的异常。

    定义一个生成器:

    >>>def fn():

    ... for i in range(10):

    ... yield i

    ...

    >>>fn() # 可以看到它是一个生成器

    Out[3]:

    >>>f = fn() # 我们得先接收这个生成器

    >>>next(f) # 然后再对生成器进行操作

    Out[6]: 0

    >>>next(f)

    Out[7]: 1

    复制代码

    从函数的执行流程中可以知道,函数执行完毕之后现场应该被销毁,但是生成器却并不是这样。

    执行流程剖析,先定义一个函数:

    >>>def g1():

    ... print('a')

    ... yield 1

    ... print('b')

    ... yield 2

    ... print('c')

    ... return 3

    ...

    >>>g = g1() # 没有输出 a,证明执行生成器函数的时候不会执行函数体

    >>>g # 可以看出是一个生成器,证明 return 没有生效

    Out[10]:

    复制代码

    通过 next 函数执行一把生成器:

    >>>next(g) # 执行到第一个 yield 后,停止执行

    a

    Out[11]: 1

    复制代码

    再执行一次:

    >>>next(g) # 从第一个 yield 之后执行,到第二个 yield 停止

    b

    Out[12]: 2

    复制代码

    继续执行:

    >>>next(g) # 从第二个 yield 之后执行,当没有更多 yield 之后,抛出异常,异常的值正好是函数的返回值

    c # 下面的语句还是会执行的

    Traceback (most recent call last):

    File "/usr/local/python/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2862, in run_code

    exec(code_obj, self.user_global_ns, self.user_ns)

    File "", line 1, in

    next(g)

    StopIteration: 3

    复制代码

    生成器函数的特点:

    生成器函数执行的时候并不会执行函数体;

    当 next 生成器的时候,会从当前代码执行到之后的第一个 yield,会弹出值并暂停函数;

    当再次 next 生成器的时候,从上次暂停处开始向下执行;

    当没有多余 yield 的时候,会抛出 StopIteration 异常,异常的 Value 是函数的返回值。

    生成器是惰性求值的。比如我们可以定义一个计数器:

    def make_inc():

    def counter():

    x = 0

    while True:

    x += 1

    yield x

    c = counter()

    return lambda: next(c)

    >>>incr = make_inc()

    >>>incr()

    Out[9]: 1

    >>>incr()

    Out[10]: 2

    复制代码

    求斐波那契数列第 11 项:

    def fib():

    a = 0

    b = 1

    while True:

    a, b = b, a+b

    yield a

    >>>f = fib()

    >>>for _ in range(10):

    ... next(f)

    ...

    >>>print(next(f))

    89

    复制代码

    可以看到递归都可以通过生成器来解决,并且没有递归深度的限制,也没有递归慢的缺点,因为它不需要保存现场。

    以上都只是生成器的普通用法,协程才是生成器的高级用法。

    进程和线程的调度是通过操作系统完成的,但是协程的调度是由用户态,也就是用户进行的。一旦函数执行到 yield 之后,它会暂停,暂停也就意味着让出 cpu 了。那么接下来就由用户决定执行什么代码。

    当我们要对一个可迭代对象的前一项或几项做特殊处理时,如果直接对其进行循环的话,我们还需要判断是不是其第一个元素,或许我们还要在其外部定义一个计数器,这其实是一种和古老和 low 的方式。有了生成器之后,我们就可以在循环之前使用 next() 函数取出其中的第一个值,然后再对其进行 for 循环即可。如果无法对其直接使用 next 方法,那就调用它的 __iter__() 方法将其变成一个生成器后再继续。

    yield

    函数中一旦使用了 yield,这个函数就变成了生成器函数。但 yield 不能和 return 共存,并且 yield 只能定义在函数中。当我们调用这个函数的时候,函数内部的代码并不立即执行,这个函数只是返回一个生成器对象。当我们使用 for 对其进行迭代的时候,函数内的代码才会被执行。

    python3 新增了 yield from 语法,它相当于 for + yield。比如:

    yield from a()

    # 等同于下面

    for i in a():

    yield i

    复制代码

    yield 和 return 的区别:

    return 的时候这个函数的局部变量都被销毁了;

    所有 return 是得到所有结果之后的返回;

    yield 是产生了一个可以恢复的函数(生成器),恢复了局部变量;

    生成器只有在调用 .next() 时才运行函数生成一个结果。

    复制代码

    yield 会记住函数执行的位置,下次再次执行时会从上次的位置继续向下执行。而如果在函数中使用 return,函数就直接退出了,无法继续执行。定义一个生成器:

    >>>def fun1(n):

    ... for i in xrange(n):

    ... yield i

    ...

    复制代码

    先执行一下:

    >>>a = fun1(5)

    >>>a.next()

    0

    复制代码

    然后再对其进行循环会从之前的地方继续向下:

    >>>for i in a:print i

    ...

    1

    2

    3

    4

    复制代码

    yield 的用处在于如果函数每次循环都会产生一个字串,如果想要将这些字串都传递给函数外的其他变量使用 return 是不行的,因为当函数第一次循环时碰到 return 语句整个函数就退出了,是不可能继续循环的,也就是说只能传递一个字串出去。这显然不符合我们的要求,这时就可以通过 yield 搞定了。

    实现xrange:

    def xrange(n):

    start = 0

    while True:

    if start >= n:

    return

    yield start

    start += 1

    复制代码

    具体案例:

    import csv

    from pyzabbix import ZabbixAPI

    zapi = ZabbixAPI('http://127.0.0.1/api_jsonrpc.php')

    zapi.login('uxeadmin', 'Uxe(00456)AdmIN.^??')

    with open('_zabbix.csv', 'w', encoding='gbk') as f:

    spamwriter = csv.writer(f)

    for i in zapi.host.get(output=["host"]):

    item_info = zapi.item.get(hostids=i['hostid'], output=["name", 'status']).__iter__()

    for j in item_info:

    if not int(j['status']):

    spamwriter.writerow([i['host'], j['name']])

    break

    for j in item_info:

    if not int(j['status']):

    spamwriter.writerow(['', j['name']])

    复制代码

    生成器方法

    请注意,在生成器已经执行时调用下面的任何生成器方法会引发 ValueError 异常。

    __next__

    开始执行一个生成器或者从上一次 yield 语句后继续执行。当使用该方法继续(注意是继续而不是第一次执行)时,那么当前 yield 的返回值为 None,直到执行到下一次的 yield 语句时,yield 语句后的表达式的结果才会返回给调用者。当迭代器结束时会抛出 StopIteration 异常。

    该方法会被 for 以及内置函数 next 隐式的调用。

    send

    继续执行生成器(注意是继续而不是第一次执行),并发送一个值到生成器函数。send 方法的参数是下一个 yield 语句的返回值,前提是 yield 语句中要事先接收它传递的参数。如果使用该方法启动(也就是第一次执行)生成器,必须使用 None 作为其参数,因为此时还没有 yield 能够接收它的值(毕竟接收该值的语句还没有开始执行)。

    def fn():

    a = 0

    while True:

    a += 1

    r = yield # r 就是接收 send 参数的变量

    print('{} => {}'.format(a, r))

    >>> f = fn()

    >>> f.send('a') # 不传递 None 的后果

    Traceback (most recent call last):

    File "/opt/python3/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2910, in run_code

    exec(code_obj, self.user_global_ns, self.user_ns)

    File "", line 1, in

    f.send('a')

    TypeError: can't send non-None value to a just-started generator

    >>> next(f) # 也可以不传递 None 而是使用 next 执行,两种方式都可以

    >>> f.send('a')

    1 => a

    >>> f.send('b')

    2 => b

    复制代码

    throw

    用法:

    throw(type[, value[, traceback]])

    复制代码

    传递一个 type 类型的异常给生成器,在生成器暂停的时候抛出,并且返回下一次 yield 的值。

    close

    在生成器函数暂停的位置引发 GeneratorExit。如果生成器函数正常退出,已经关闭,或者引发 GeneratorExit(没有捕获该异常),关闭返回给调用者;如果生成器产生一个值,则引发一个 RuntimeError;如果生成器引发其他异常,则传播给调用者;如果生成器由于异常或正常退出而退出,则 close() 不执行任何操作。

    示例

    >>> def echo(value=None):

    ... print("Execution starts when 'next()' is called for the first time.")

    ... try:

    ... while True:

    ... try:

    ... value = (yield value) # 不管 yield 后面是否有表达式,value 的值都是 send 传递进来的参数

    ... except Exception as e:

    ... value = e

    ... finally:

    ... print("Don't forget to clean up when 'close()' is called.")

    ...

    >>> generator = echo(1)

    >>> print(next(generator))

    Execution starts when 'next()' is called for the first time.

    1

    >>> print(next(generator))

    None

    >>> print(generator.send(2))

    2

    >>> generator.throw(TypeError, "spam")

    TypeError('spam',)

    >>> generator.close()

    Don't forget to clean up when 'close()' is called.

    复制代码

    生成器解析

    python3 中的 range 函数就是一个典型的生成器,无论给它一个多么大的数,它占用内存始终很小。但是下面的代码会返回一个占用空间很大的列表:

    [x ** 2 for x in range(100000)]

    复制代码

    当我们想让它返回的结果也像生成器一样可以将中括号换成小括号:

    >>>(x ** 2 for x in range(100000))

    at 0x7fb246656620>

    复制代码

    使用 next 函数就可以查看里面的每个值,当然 for 循环也可以。

    因此将列表解析的中括号变成小括号就是生成器的语法。

    生成器解析其实就是列表解析的扩展,当我们明确需要使用小标访问的时候,使用列表解析。而如果只需要对结果进行迭代的时候,优先使用生成器解析。

    还有一个场景,就是要对结果进行缓存的时候,就只能使用列表解析了。不过使用生成器解析的场景确实要比列表解析来的多。

    暴露生成器内的对象

    如果你想让你的生成器暴露外部状态给用户, 别忘了你可以简单的将它实现为一个类,然后把生成器函数放到 __iter__() 方法中过去。比如:

    from collections import deque

    class linehistory:

    def __init__(self, lines, histlen=3):

    self.lines = lines

    self.history = deque(maxlen=histlen)

    def __iter__(self):

    for lineno, line in enumerate(self.lines, 1):

    self.history.append((lineno, line))

    yield line

    def clear(self):

    self.history.clear()

    复制代码

    为了使用这个类,你可以将它当做是一个普通的生成器函数。然而,由于可以创建一个实例对象,于是你可以访问内部属性值,比如 history 属性或者是 clear() 方法。代码示例如下:

    with open('somefile.txt') as f:

    lines = linehistory(f)

    for line in lines:

    if 'python' in line:

    for lineno, hline in lines.history:

    print('{}:{}'.format(lineno, hline), end='')

    复制代码

    如果行中包含了 python 这个关键字,那就打印该行和前三行的行号以及内容。

    关于生成器,很容易掉进函数无所不能的陷阱。如果生成器函数需要跟你的程序其他部分打交道的话(比如暴露属性值,允许通过方法调用来控制等等),可能会导致你的代码异常的复杂。如果是这种情况的话,可以考虑使用上面介绍的定义类的方式。在 __iter__() 方法中定义你的生成器不会改变你任何的算法逻辑。由于它是类的一部分,所以允许你定义各种属性和方法来供用户使用。

    一个需要注意的小地方是,如果你在迭代操作时不使用 for 循环语句,那么你得先调用 iter() 函数。比如:

    >>>f = open('somefile.txt')

    >>>lines = linehistory(f)

    >>>next(lines)

    Traceback (most recent call last):

    File "", line 1, in

    TypeError: 'linehistory' object is not an iterator

    >>># Call iter() first, then start iterating

    >>>it = iter(lines)

    >>>next(it)

    'hello world\n'

    >>>next(it)

    'this is a test\n'

    >>>

    复制代码

    生成器切片

    你想得到一个由迭代器生成的切片对象,但是标准切片操作并不能做到。函数 itertools.islice() 正好适用于在迭代器和生成器上做切片操作。比如:

    >>>def count(n):

    ... while True:

    ... yield n

    ... n += 1

    ...

    >>>c = count(0)

    >>>c[10:20]

    Traceback (most recent call last):

    File "", line 1, in

    TypeError: 'generator' object is not subscriptable

    >>># Now using islice()

    >>>import itertools

    >>>for x in itertools.islice(c, 10, 20):

    ... print(x)

    ...

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    >>>

    复制代码

    迭代器和生成器不能使用标准的切片操作,因为它们的长度事先我们并不知道(并且也没有实现索引)。函数 islice() 返回一个可以生成指定元素的迭代器,它通过遍历并丢弃直到切片开始索引位置的所有元素。然后才开始一个个的返回元素,并直到切片结束索引位置。

    这里要着重强调的一点是 islice() 会消耗掉传入的迭代器中的数据。必须考虑到迭代器是不可逆的这个事实。所以如果你需要之后再次访问这个迭代器的话,那你就得先将它里面的数据放入一个列表中。

    跳过可迭代对象开始部分

    你想遍历一个可迭代对象,但是它开始的某些元素你并不感兴趣,想跳过它们。itertools 模块中有一些函数可以完成这个任务。首先介绍的是 itertools.dropwhile() 函数。使用时,你给它传递一个函数对象和一个可迭代对象。它会返回一个迭代器对象,丢弃原有序列中直到函数返回 Flase 之前的所有元素,然后返回后面所有元素。

    为了演示,假定你在读取一个开始部分是几行注释的源文件。比如:

    >>>with open('/etc/passwd') as f:

    ...for line in f:

    ... print(line, end='')

    ...

    ##

    # User Database

    #

    # Note that this file is consulted directly only when the system is running

    # in single-user mode. At other times, this information is provided by

    # Open Directory.

    ...

    ##

    nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false

    root:*:0:0:System Administrator:/var/root:/bin/sh

    ...

    >>>

    复制代码

    如果你想跳过开始部分的注释行的话,可以这样做:

    >>>from itertools import dropwhile

    >>>with open('/etc/passwd') as f:

    ... for line in dropwhile(lambda line: line.startswith('#'), f):

    ... print(line, end='')

    ...

    nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false

    root:*:0:0:System Administrator:/var/root:/bin/sh

    ...

    >>>

    复制代码

    这个例子是基于根据某个测试函数跳过开始的元素。如果你已经明确知道了要跳过的元素的个数的话,那么可以使用 itertools.islice() 来代替。比如:

    >>>from itertools import islice

    >>>items = ['a', 'b', 'c', 1, 4, 10, 15]

    >>>for x in islice(items, 3, None):

    ... print(x)

    ...

    1

    4

    10

    15

    >>>

    复制代码

    在这个例子中,islice() 函数最后那个 None 参数指定了你要获取从第 3 个到最后的所有元素。如果 None 和 3 的位置对调,意思就是仅仅获取前三个元素,这个跟切片的相反操作 [3:] 和 [:3] 原理是一样的。

    函数 dropwhile() 和 islice() 其实就是两个帮助函数,为的就是避免写出下面这种冗余代码:

    with open('/etc/passwd') as f:

    # Skip over initial comments

    while True:

    line = next(f, '')

    if not line.startswith('#'):

    break

    # Process remaining lines

    while line:

    # Replace with useful processing

    print(line, end='')

    line = next(f, None)

    复制代码

    跳过一个可迭代对象的开始部分跟通常的过滤是不同的。比如,上述代码的第一个部分可能会这样重写:

    with open('/etc/passwd') as f:

    lines = (line for line in f if not line.startswith('#'))

    for line in lines:

    print(line, end='')

    复制代码

    这样写确实可以跳过开始部分的注释行,但是同样也会跳过文件中其他所有的注释行。换句话讲,我们的解决方案是仅仅跳过开始部分满足测试条件的行,在那以后,所有的元素不再进行测试和过滤了。

    最后需要着重强调的一点是,本节的方案适用于所有可迭代对象,包括那些事先不能确定大小的,比如生成器,文件及其类似的对象。

    展开嵌套的序列

    你想将一个多层嵌套的序列展开成一个单层列表,可以写一个包含 yield from 语句的递归生成器来轻松解决这个问题。比如:

    from collections import Iterable

    def flatten(items, ignore_types=(str, bytes)):

    for x in items:

    if isinstance(x, Iterable) and not isinstance(x, ignore_types):

    yield from flatten(x)

    else:

    yield x

    items = [1, 2, [3, 4, [5, 6], 7], 8]

    # Produces 1 2 3 4 5 6 7 8

    for x in flatten(items):

    print(x)

    复制代码

    在上面代码中,isinstance(x, Iterable) 检查某个元素是否是可迭代的。如果是的话,yield from 就会返回所有子例程的值。最终返回结果就是一个没有嵌套的简单序列了。

    额外的参数 ignore_types 和检测语句 isinstance(x, ignore_types) 用来将字符串和字节排除在可迭代对象外,防止将它们再展开成单个的字符。 这样的话字符串数组就能最终返回我们所期望的结果了。比如:

    >>>items = ['Dave', 'Paula', ['Thomas', 'Lewis']]

    >>>for x in flatten(items):

    ... print(x)

    ...

    Dave

    Paula

    Thomas

    Lewis

    >>>

    复制代码

    之前提到的对于字符串和字节的额外检查是为了防止将它们再展开成单个字符。如果还有其他你不想展开的类型,修改参数 ignore_types 即可。

    最后要注意的一点是,yield from 在涉及到基于协程和生成器的并发编程中扮演着更加重要的角色。

    展开全文
  • 字符串是可迭代对象,是序列中的有序序列,即可迭代对象就是有序序列。无序序列(无序的对象)比如字典类型也可用for循环 for item in'我想上青天': print(item) test=12345 for k in test: print(k) #...

    for 变量名 in 序列

    字符串是可迭代对象,是序列中的有序序列,即可迭代对象就是有序序列。无序序列(无序的对象)比如字典类型也可用for循环

    for item in'我想上青天':
      print(item)
    test=12345
    for k in test:
        print(k)    #数字类型的话报错
    for k in range(1,6):
        print(k)    
    test=12345
    test=str(test)  #先把数字类型转化为字符串类型
    for k in test:
      print(k)
    
    

     

     

     

    转载于:https://www.cnblogs.com/ss-lu/p/9910175.html

    展开全文
  • Python可迭代对象

    千次阅读 多人点赞 2019-10-08 14:50:26
    int、float、bool称为不可迭代对象 str、list、tuple、set、dict称为可迭代对象 可以用isinstance()判断是否是可迭代对象 格式:isinstance(obj, Iterable) 返回值:bool类型 # 可迭代对象案例 from collections...

    可迭代对象

    可以用for…in…这类语句迭代读取一条数据供我们使用的对象称为可迭代对象

    • int、float、bool称为不可迭代对象
    • str、list、tuple、set、dict称为可迭代对象
    • 可以用isinstance()判断是否是可迭代对象
      • 格式:isinstance(obj, Iterable)
      • 返回值:bool类型
    # 可迭代对象案例
    from collections import Iterable
    
    a = int()
    b = float()
    c = bool()
    d = str()
    e = list()
    f = tuple()
    g = set()
    h = dict()
    
    print(isinstance(a, Iterable))
    print(isinstance(b, Iterable))
    print(isinstance(c, Iterable))
    print(isinstance(d, Iterable))
    print(isinstance(e, Iterable))
    print(isinstance(f, Iterable))
    print(isinstance(g, Iterable))
    print(isinstance(h, Iterable))
    
    """
    运行结果:
    False
    False
    False
    True
    True
    True
    True
    True
    """
    

    列表(list)

    一组有顺序的数据的组合

    • 列表中的元素有先后顺序
    • 列表中的元素可以是不同类型的
    • 列表用“[]”包含
    # list案例1
    l1 = [1, 2, 3, 'Hello', 'World']
    l2 = list()
    l3 = []
    
    print(type(l1))
    print(l1)
    print(type(l2))
    print(l2)
    print(type(l3))
    print(l3)
    
    """
    运行结果:
    <class 'list'>
    [1, 2, 3, 'Hello', 'World']
    <class 'list'>
    []
    <class 'list'>
    []
    """
    
    # list案例2
    s = 'Mad man'
    
    l1 = list(s)
    l2 = [s]
    
    print(type(l1))
    print(l1)
    print(type(l2))
    print(l2)
    
    """
    运行结果:
    <class 'list'>
    ['M', 'a', 'd', ' ', 'm', 'a', 'n']
    <class 'list'>
    ['Mad man']
    """
    

    列表的常见操作

    访问

    • 使用下标操作,也叫索引
    • 格式:list[index]
    • 列表的元素索引从0开始
    • 索引超过列表范围会报错
    # 列表访问案例
    l1 = [1, 2, 3, 4, 5]
    
    print(l1[2])
    print(l1[100])
    
    """
    运行结果:
    3
    IndexError: list index out of range
    """
    

    切片

    对列表进行任意一段的截取

    • 使用下标操作,也叫索引
    • 左索引包括,右索引不包括
    • 格式:list[index1: index2: step]
      • index1:左索引,可以为空,默认为方向上的起点
      • index2:右索引,可以为空,默认为方向上的终点
      • step:步长,默认为1,如果是负数,则方向从右往左
    • 左右索引都为空时,默认包含整个列表
    • 列表最后一个数据的索引是-1
    • 切片后生成的列表是一个全新的列表
    # 列表切片案例1
    l1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    l2 = l1[0: 9]
    l3 = l1
    
    print(id(l1))
    print(l1)
    print(id(l2))
    print(l1)
    print(id(l3))
    print(l3)
    
    """
    运行结果:
    2290380530184
    [1, 2, 3, 4, 5, 6, 7, 8, 9]
    2290380530248
    [1, 2, 3, 4, 5, 6, 7, 8, 9]
    2290380530184
    [1, 2, 3, 4, 5, 6, 7, 8, 9]
    """
    
    # 列表切片案例2
    l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    print(l[:4])
    print(l[4:])
    print(l[:])
    
    """
    运行结果:
    [1, 2, 3, 4]
    [5, 6, 7, 8, 9]
    [1, 2, 3, 4, 5, 6, 7, 8, 9]
    """
    
    # 列表切片案例3
    l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    print(l[::])
    print(l[::2])
    
    """
    运行结果:
    [1, 2, 3, 4, 5, 6, 7, 8, 9]
    [1, 3, 5, 7, 9]
    """
    
    • 索引可以超出范围,超出后不再考虑多余索引内容
    # 列表切片案例4
    l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    print(l[:100])
    
    """
    运行结果:
    [1, 2, 3, 4, 5, 6, 7, 8, 9]
    """
    
    • 索引值可以为负数
      • 索引值为负数时,表示顺序从右往左
      • 列表的最后一个元素索引值为-1
    • 注意:列表访问的默认顺序是从左往右
    # 列表切片案例5
    l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    
    print(l[-2:-5])
    print(l[-2:-5:-1])
    print(l[-5:-2])
    
    """
    运行结果:
    []
    [8, 7, 6]
    [5, 6, 7]
    """
    

    加法和乘法

    • 加法操作用操作符“+
    • 乘法操作用操作符“*
    # 列表的加法乘法操作
    l1 = [1, 2, 3]
    l2 = ['one', 'two', 'three']
    l3 = l1 + l2
    
    print(l3)
    print(l3 * 2)
    
    """
    运行结果:
    [1, 2, 3, 'one', 'two', 'three']
    [1, 2, 3, 'one', 'two', 'three', 1, 2, 3, 'one', 'two', 'three']
    """
    

    成员检测

    • 用“in”和“not in
    • 返回值是一个布尔值
    # 列表的成员检测案例
    l = ['I', 'am', 'madman', 1, 2, 3]
    
    if 'madman' in l:
        print('在!')
    if 4 not in l:
        print('不在!')
        
    """
    运行结果:
    在!
    不在!
    """
    

    嵌套

    • 列表可以嵌套操作
    • 可以用多层循环或单层循环访多层嵌套的内容
    #  列表嵌套案例
    l = [[1, 2, 3], [4, 5, 6]]
    
    # 多层循环访问
    for i in l:
        print(i)
        for j in i:
            print(j)
            
    # 单层循环访问
    for i, j, k in l:
        print(i, j, k)
            
     """
     运行结果:
    [1, 2, 3]
    1
    2
    3
    [4, 5, 6]
    4
    5
    6
    1 2 3
    4 5 6
     """
    

    生成式

    • 可用生成式更便利地生成集合
    • 格式:[i for i in list if xxx]
    # 列表生成式案例
    l1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    l2 = [2, 3]
    l3 = [i for i in l1]
    l4 = [i for i in l1 if i % 2 == 0]
    l5 = [i**2 for i in l1]
    l6 = [m*n for m in l1 for n in l2]
    l7 = [i for i in range(0, 11)]
    
    print(l3)
    print(l4)
    print(l5)
    print(l6)
    print(l7)
    
    """
    运行结果:
    [1, 2, 3, 4, 5, 6, 7, 8, 9]
    [2, 4, 6, 8]
    [1, 4, 9, 16, 25, 36, 49, 64, 81]
    [2, 3, 4, 6, 6, 9, 8, 12, 10, 15, 12, 18, 14, 21, 16, 24, 18, 27]
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    """
    

    删除

    可以删除指定的内容

    • 格式:del list/list[index]
    # 列表删除案例
    l = [1, 2, 3, 4]
    
    del l[1]
    print(l)
    
    del l[0: 2]
    print(l)
    
    del l
    print(l)
    
    """
    运行结果:
    [1, 3, 4]
    [4]
    NameError: name 'l' is not defined
    """
    

    列表的常用函数

    • len:求列表长度:len(list)
    • max:求列表中的最大值:max(list)
    • min:求列表中的最小值:min(list)
    • list:将其他格式的数据转换成list:list(object)
    • append:在末尾追加内容:list.append(value)
    • insert:在任何位置插入内容:insert(index, value),如果没有那个索引会报错
    • pop:对可变序列中元素索引进行检索删除,默认索引为-1返回删除值:list.pop(index)
    • remove:直接对可变序中的元素进行检索删除,返回的是删除后的列表,不返回删除值,如果没有那个值会报错:list.remove(index)
    • clear:清空列表:list.clear()
    • reverse:翻转:list.reverse()
    • extend:扩展列表,在A列表后面拼接B列表:listA.extend(listB)
    • count:查找列表中指定值或元素的个数并返回:list.count(value)
    • copy:浅拷贝:list.copy()
    • index:查找元素所在下标:list.index(value)
    • sort:按照ASCII顺序进行排序:list.sort()

    元组(tuple)

    可以理解成一个不允许更改的列表

    • 元组中的元素不可修改,但是元组本身可以改变
    • 元组中的元素有先后顺序
    • 元组中的元素可以是不同类型的
    • 元组用“()”包含
    • 注意:创建只有一个元素的元组时,要在第一个元素后面加逗号
    # tuple案例
    t1 = ()
    t2 = tuple()
    t3 = (100)
    t4 = (100,)
    t5 = 100,
    t6 = 100, 200
    
    print(type(t1))
    print(t1)
    print(type(t2))
    print(t2)
    print(type(t3))
    print(t3)
    print(type(t4))
    print(t4)
    print(type(t5))
    print(t5)
    print(type(t6))
    print(t6)
    
    """
    运行结果:
    <class 'tuple'>
    ()
    <class 'tuple'>
    ()
    <class 'int'>
    100
    <class 'tuple'>
    (100,)
    <class 'tuple'>
    (100,)
    <class 'tuple'>
    (100, 200)
    """
    

    元组的常见操作

    元组的常见操作和列表类似

    • 元组的内容不可以更改
    • 元组无法使用生成式
    # 元组的访问切片案例
    t = ('I', 'am', 'Madman')
    
    # 访问操作
    print(t)
    print(t[2])
    print(t[100])
    
    # 切片操作
    print(t[:])
    print(t[-1::-1])
    print(t[::-1])
    
    """
    运行结果:
    ('I', 'am', 'Madman')
    Madman
    IndexError: tuple index out of range
    ('I', 'am', 'Madman')
    ('Madman', 'am', 'I')
    ('Madman', 'am', 'I')
    """
    
    # 元组的加法乘法案例
    t1 = 1, 2, 3
    t2 = 'I', 'am', 'madman'
    t3 = t1 + t2
    print(type(t3))
    print(t3)
    
    t4 = t3 * 2
    print(type(t4))
    print(t4)
    
    """
    运行结果:
    <class 'tuple'>
    (1, 2, 3, 'I', 'am', 'madman')
    <class 'tuple'>
    (1, 2, 3, 'I', 'am', 'madman', 1, 2, 3, 'I', 'am', 'madman')
    """
    
    # 元组的in和not in案例
    t = (1, 2, 3)
    if 1 in t:
        print('在!')
    if 4 not in t:
        print('不在!')
        
    """
    运行结果:
    在!
    不在!
    """
    
    # 元组的循环访问案例
    t = ([1, 2, 3], [4, 5], (7, 8, 9))
    
    # 多层循环访问
    for i in t:
        print(i)
        for j in i:
            print(j)
    print('*' * 20)
    
    # 单层循环访问,i, j, k要和元组的元素个数对应,否则报错
    for i, j, k in t:
        print(i, j, k)
    
    """
    运行结果:
    [1, 2, 3]
    1
    2
    3
    [4, 5]
    4
    5
    (7, 8, 9)
    7
    8
    9
    ********************
    1 2 3   
    ValueError: not enough values to unpack (expected 3, got 2)
    """
    
    # 元组生成式案例
    t1 = (1, 2, 3, 4, 5, 6, 7, 8, 9)
    t2 = (2, 3)
    t3 = (i for i in t1)
    t4 = (i for i in t1 if i % 2 == 0)
    t5 = (i**2 for i in t1)
    t6 = (m*n for m in t1 for n in t2)
    t7 = (i for i in range(0, 11))
    
    print(t3)
    print(t4)
    print(t5)
    print(t6)
    print(t7)
    
    """
    运行结果:
    <generator object <genexpr> at 0x0000029E8CC8C390>
    <generator object <genexpr> at 0x0000029E8CC8C5E8>
    <generator object <genexpr> at 0x0000029E8CC8C660>
    <generator object <genexpr> at 0x0000029E8CC8C6D8>
    <generator object <genexpr> at 0x000002A6B320C7C8>
    """
    
    # 元组的删除案例
    t = (1, 2, 3, 4, 5)
    
    # 因为元组的内容不可以改变,所以删除内容会报错
    del t[1]
    print(t)
    
    del t[0: 2]
    print(t)
    
    del t
    print(t)
    
    """
    TypeError: 'tuple' object does not support item deletion
    TypeError: 'tuple' object does not support item deletion
    NameError: name 't' is not defined
    """
    

    集合(set)

    没有顺序且没有重复元素的一组数据

    • 集合中的元素不重复
    • 集合中的元素没有固定的顺序
    • 集合中的元素可以是不同类型的
    • 元组用“{}”包含
    • 注意
      • 集合内部只可以存放可哈希数据
      • 可哈希:生命周期内不可改变值的对象(str、int、float、tuple、对象集object等)
      • 不可哈希类型:list、set、dict
    # set案例
    s1 = {}
    s2 = set()
    s3 = {1, 2, 3, 'I', 'am', 'madman', (1, 2, 3)}
    s4 = {1, 2, 3, [1, 2, 3]}
    s5 = {1, 2, 3, ([1, 2, 3], [4, 5, 6])}
    s6 = {1, 2, 3, {1, 2, 3}}
    s7 = {1, 2, 3, ({1, 2, 3}, {4, 5, 6})}
    
    print(type(s1))
    print(s1)
    print(type(s2))
    print(s2)
    print(type(s3))
    print(s3)
    print(type(s4))
    print(s4)
    print(type(s5))
    print(s5)
    print(type(s6))
    print(s6)
    print(type(s7))
    print(s7)
    
    """
    运行结果:
    <class 'dict'>
    {}
    <class 'set'>
    set()
    <class 'set'>
    {1, 2, 3, 'I', (1, 2, 3), 'madman', 'am'}
    TypeError: unhashable type: 'list'
    TypeError: unhashable type: 'list'
    TypeError: unhashable type: 'set'
    TypeError: unhashable type: 'set'
    """
    

    集合的常见操作

    集合的常见操作类似列表

    • 集合不可进行访问切片操作
    • 集合不可进行加法乘法操作
    # 集合的访问切片案例
    s = {1, 2, 3, 4, 5, 6}
    
    print(s[1])
    print(s[0: 4])
    
    """
    运行结果:
    TypeError: 'set' object does not support indexing
    TypeError: 'set' object is not subscriptable
    """
    
    # 集合的加法乘法案例
    s1 = {1, 2, 3}
    s2 = {'I', 'am', 'madman'}
    s3 = s1 + s2 
    print(type(s3))
    print(s3)
    
    s4 = s1 * 2
    print(type(s4))
    print(s4)
    
    """
    运行结果:
    TypeError: unsupported operand type(s) for +: 'set' and 'set'
    TypeError: unsupported operand type(s) for *: 'set' and 'int'
    """
    
    # 集合的in和not in操作
    s = {1, 2, 3, 4, 'Madman', (1, 2, 3)}
    
    if (1, 2, 3) in s:
        print('在!')
    if 'madman' not in s:
        print('不在!')
        
    """
    运行结果:
    在!
    不在!
    """
    
    # 集合的循环访问案例
    s1 = {1, 2, 3, 4, 5, 6, (1, 2, 3), (4, 5, 6)}
    s2 = {(1, 2, 3), (4, 5, 6), (1, 2, 3)}
    s3 = {(1, 2, 3), (4, 5, 6), (1, 2)}
    
    for i in s1:
        print(i)
    for i, j, k in s2:
        print(i, j, k)
    for i, j, k in s3:
        print(i, j, k)
        
    """
    运行结果:
    1
    2
    3
    4
    5
    6
    (1, 2, 3)
    (4, 5, 6)
    4 5 6
    1 2 3
    ValueError: not enough values to unpack (expected 3, got 2)
    """
    
    # 集合的生成式案例
    s1 = {1, 2, 3, 4, 5, 6, 7, 8, 9}
    s2 = {2, 3}
    s3 = {i for i in s1}
    s4 = {i for i in s1 if i % 2 == 0}
    s5 = {i**2 for i in s1}
    s6 = {m*n for m in s1 for n in s2}
    s7 = {i for i in range(0, 11)}
    
    print(s3)
    print(s4)
    print(s5)
    print(s6)
    print(s7)
    
    """
    运行结果:
    {1, 2, 3, 4, 5, 6, 7, 8, 9}
    {8, 2, 4, 6}
    {64, 1, 4, 36, 9, 16, 49, 81, 25}
    {2, 3, 4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 21, 24, 27}
    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    """
    
    # 集合的删除案例
    s = {1, 2, 3, 4}
    
    del s[2]
    print(s)
    
    del s
    print(s)
    
    """
    运行结果:
    TypeError: 'set' object doesn't support item deletion
    NameError: name 's' is not defined
    """
    

    集合的数学操作

    • intersection():交集
      • 格式:set1.intersection(set2)
      • 返回值:计算结果,set类型
    • difference():差集
      • 格式:set1.difference(set2)
      • 返回值:计算结果,set类型
      • 可以用“-”号表示
    • union():并集
      • 格式:set1.union(set2)
      • 返回值:计算结果,set类型
    # 集合的数学操作案例1
    s1 = {1, 2, 3, 4}
    s2 = {3, 4, 5, 6}
    
    print(s1.intersection(s2))
    print(s1.difference(s2))
    print(s1 - s2)
    print(s1.union(s2))
    print(s1 + s2)
    
    """
    运行结果:
    {3, 4}
    {1, 2}
    {1, 2}
    {1, 2, 3, 4, 5, 6}
    TypeError: unsupported operand type(s) for +: 'set' and 'set'
    """
    
    • issubset:检查一个集合是否为另一个集合的子集
      • 格式:set1.issubset(set2)
      • 返回值:布尔值
    • issuperset:检查一个集合是否为另一个集合的超集
      • 格式:set1.issuperset(set2)
      • 返回值:布尔值
    # 集合的数学操作案例2
    s1 = {1, 2, 3}
    s2 = {1, 2, 3, 4}
    
    print(s1.issubset(s2))
    print(s2.issuperset(s1))
    
    """
    运行结果:
    True
    True
    """
    

    frozenset(冰冻集合)

    不可以修改的集合

    list、tuple、set转换问题

    • list、tuple、set之间的转换,转换的内容必须是可迭代的
    • list、tuple转换成set时,set会对数字进行从小到大的排序
    # list、tuple、set转换问题案例
    a = 100
    b = [100]
    c = (5, 23, 4, 6, 9, 0, 23)
    
    t1 = tuple(a)
    print(type(t1))
    print(t1)
    
    t2 = tuple(b)
    print(type(t2))
    print(t2)
    
    s1 = set(a)
    print(type(s1))
    print(s1)
    
    s2 = set(b)
    print(type(s2))
    print(s2)
    
    s3 = set(c)
    print(type(s3))
    print(s3)
    
    """
    TypeError: 'int' object is not iterable
    <class 'tuple'>
    (100,)
    TypeError: 'int' object is not iterable
    <class 'set'>
    {100}
    <class 'set'>
    {0, 4, 5, 6, 9, 23}
    """
    

    字典(dict)

    一种键值对形式的组合数据

    • 字典是序列类型,无序,所以没有切片和索引操作
    • 字典中的每个数据都由键值对组成,即kv对
      • key:必须是可哈希的,比如int,string,float,tuple
      • value:任何值
    #  dict案例
    d1 = {}
    d2 = {1: '1', '2': 2, (1, 2, 3): [1, 2, 3], 1.1: {1: {1, 2, 3}}}
    
    print(type(d1))
    print(d1)
    print(type(d2))
    print(d2)
    
    """
    运行结果:
    <class 'dict'>
    {}
    <class 'dict'>
    {1: '1', '2': 2, (1, 2, 3): [1, 2, 3], 1.1: {1: {1, 2, 3}}}
    """
    

    字典的常见操作

    # 访问修改删除数据操作案例
    d = {'one': 1, 'two': 2, 3: 'three'}
    
    print(d['one'])
    
    # 修改数据
    d['one'] = 'Hello'
    print(d)
    
    # 删除数据
    del d['one']
    print(d)
    
    """
    运行结果:
    1
    {'one': 'Hello', 'two': 2, 3: 'three'}
    {'two': 2, 3: 'three'}
    """
    
    # 成员检测案例
    # 成员检测时,检测的是key的内容
    d = {'one': 1, 'two': 2, 'three': 3}
    if 2 in d:
        print('value')
    if 'two' in d:
        print('key')
    if ('two', 2) in d:
        print('key and value')
        
    """
    运行结果:
    key
    """
    
    # dict的循环访问案例
    d = {'one': 1, 'two': 2, 'three': 3}
    for k in d:
        print(k, '--', d[k])
        
    print('*' * 20)
    
    for k in d.keys():
        print(k)
        
    for v in d.values():
        print(v)
        
    for k,v in d.items():
        print(k, '--', v)
        
    """
    运行结果:
    one -- 1
    two -- 2
    three -- 3
    ********************
    one
    two
    three
    1
    2
    3
    one -- 1
    two -- 2
    three -- 3
    """
    
    # 字典的生成式案例
    d1 = {'one': 1, 'two': 2, 'three': 3, 'four': 4}
    d2 = {k: v for k, v in d1.items() if v % 2 == 0}
    d3 = {k: 'None' for k in range(0, 5)}
    
    print(d2)
    print(d3)
    
    """
    运行结果:
    {'two': 2, 'four': 4}
    {0: 'None', 1: 'None', 2: 'None', 3: 'None', 4: 'None'}
    """
    
    # 字典变成其他类型案例
    d = {'one': 1, 'two': 2, 'three': 3, 'four': 4}
    st = str(d)
    l = list(d)
    t = tuple(d)
    se = set(d)
    
    print(type(st))
    print(st)
    print(type(l))
    print(l)
    print(type(t))
    print(t)
    print(type(se))
    print(se)
    
    """
    运行结果:
    <class 'str'>
    {'one': 1, 'two': 2, 'three': 3, 'four': 4}
    <class 'list'>
    ['one', 'two', 'three', 'four']
    <class 'tuple'>
    ('one', 'two', 'three', 'four')
    <class 'set'>
    {'two', 'four', 'one', 'three'}
    """
    

    字典常用函数

    items()

    获取字典的键值对

    • 格式:dict.items()
    • 返回值:字典的键值对组成的元组结构
    # items()案例
    d = {'one': 1, 'two': 2, 'three': 3}
    i = d.items()
    print(type(d))
    print(d)
    print(type(i))
    print(i)
    
    """
    运行结果:
    <class 'dict'>
    {'one': 1, 'two': 2, 'three': 3}
    <class 'dict_items'>
    dict_items([('one', 1), ('two', 2), ('three', 3)])
    """
    

    keys()

    获取字典的键

    • 格式:dict.keys()
    • 返回值:字典的键组成的元组结构
    # keys()案例
    d = {'one': 1, 'two': 2, 'three': 3}
    k = d.keys()
    
    print(type(k))
    print(k)
    
    """
    运行结果:
    <class 'dict_keys'>
    dict_keys(['one', 'two', 'three'])
    """
    

    values()

    获取字典的值

    • 格式:dict.values()
    • 返回值:字典的值组成的元组结构
    # values()案例
    d = {'one': 1, 'two': 2, 'three': 3}
    v = d.values()
    
    print(type(v))
    print(v)
    
    """
    运行结果:
    <class 'dict_values'>
    dict_values([1, 2, 3])
    """
    

    get()

    根据指定的键返回相应的值,和普通方法相比,get()可以设置默认值

    • 格式:dict.get(key, default_value)
    • 返回值:字典的值或设置的默认值
    # get()案例
    d = {'one': 1, 'two': 2, 'three': 3}
    print(d.get("four"))
    
    # get的默认值是None,可以设置
    print(d.get("one", 100))
    print(d.get("four", 100))
    
    print(d["four"])
    
    """
    运行结果:
    None
    1
    100
    KeyError: 'four'
    """
    

    fromkeys()

    使用指定的序列作为键,使用一个值作为所有键的值

    • 格式:dict.fromkeys(sequence, value)
    • 返回值:生成一个字典
    # fromkeys()案例
    l = ['Guitar', 'Write', 'Code']
    d = dict.fromkeys(l, 'Good')
    
    print(type(d))
    print(d)
    
    """
    运行结果:
    <class 'dict'>
    {'Guitar': 'Good', 'Write': 'Good', 'Code': 'Good'}
    """
    

    可迭代对象常用函数

    len()

    获取长度

    • 格式:len(str/list/tuple/set/dict...)
    • 返回值:int类型的数字(表示长度)
    # len()案例
    st = 'I am madman'
    l = [1, 2, 3, 4, 5, (1, 2, 3, 4, 5)]
    t = (1, 2, 3, 4, 5, {1, 2, 3, 4, 5})
    se = {1, 2, 3, 4, 5, (1, 2, 3, 4, 5)}
    d = {'name': 'Madman', 'age': 23, 'local': 'Shenzhen'}
    
    print(type(len(st)))
    print(len(st))
    print(type(len(l)))
    print(len(l))
    print(type(len(t)))
    print(len(t))
    print(type(len(se)))
    print(len(se))
    print(type(len(d)))
    print(len(d))
    
    """
    运行结果:
    <class 'int'>
    11
    <class 'int'>
    6
    <class 'int'>
    6
    <class 'int'>
    6
    <class 'int'>
    3
    """
    

    min()/max()

    求最小值/最大值

    • 格式:min/max(str/list/tuple/set/dict...)
    • 返回值:最小值/最大值的内容,一般是int或str
    • 注意:不同类型的数据使用min()/max()会报错,因为函数本质上是数据的对比
    # min()/max()案例
    l1 = [77, 44, 99, 1, 34]
    l2 = ['a', 'ab', 'A', 'AB']
    l3 = [1, 2, 'Madman']
    l4 = [1, 2, (1, 2, 3)]
    
    st = 'I am madman'
    t = ('I', 'am', 'madman', 'me')
    se = {1, 2, 3, 4, 5, 77, 88}
    d = {'name': 'Madman', 'age': 23, 'local': 'Shenzhen'}
    
    print(type(max(l1)))
    print(max(l1))
    print(type(max(l2)))
    print(max(l2))
    print(type(max(l3)))
    print(max(l3))
    print(type(max(l4)))
    print(max(l4))
    
    print(type(max(st)))
    print(max(st))
    print(type(max(t)))
    print(max(t))
    print(type(max(se)))
    print(max(se))
    print(type(max(d)))
    print(max(d))
    
    """
    运行结果:
    <class 'int'>
    99
    <class 'str'>
    ab
    TypeError: '>' not supported between instances of 'str' and 'int'
    TypeError: '>' not supported between instances of 'tuple' and 'int'
    <class 'str'>
    n
    <class 'str'>
    me
    <class 'int'>
    88
    <class 'str'>
    name
    """
    

    count()

    对某一元素进行计数

    • 格式:str/list/tuple.count(value)
    • 返回值:int类型的数字(表示数目)
    • 注意:set和dict无法使用
    # count()案例
    st = 'I am madman'
    l = [1, 2, 3, 4, 5, (1, 2, 3, 4, 5), 1, 2, 2]
    t = (1, 2, 3, 4, 5, {1, 2, 3, 4, 5}, 1, 2, 2)
    se = {1, 2, 3, 4, 5, (1, 2, 3, 4, 5), 1, 2, 2}
    d = {'name': 'Madman', 'age': 23, 'local': 'Shenzhen'}
    
    print(type(st.count('m')))
    print(st.count('m'))
    print(type(l.count(2)))
    print(l.count(2))
    print(type(t.count(2)))
    print(t.count(2))
    print(type(se.count(2)))
    print(se.count(2))
    print(type(d.count('name')))
    print(d.count('name'))
    
    """
    返回结果:
    <class 'int'>
    3
    <class 'int'>
    3
    <class 'int'>
    3
    AttributeError: 'set' object has no attribute 'count'
    AttributeError: 'dict' object has no attribute 'count'
    """
    

    index()

    某一元素从左往右第一次出现的位置

    • 格式:obj.index(value)
    • 返回值:int类型的数字(表示位置)
    • 注意:set和dict无法使用
    # index()案例
    st = 'I am madman'
    l = [1, 2, 3, 4, 5, (1, 2, 3, 4, 5), 1, 2, 2]
    t = (1, 2, 3, 4, 5, {1, 2, 3, 4, 5}, 1, 2, 2)
    se = {1, 2, 3, 4, 5, (1, 2, 3, 4, 5), 1, 2, 2}
    d = {'name': 'Madman', 'age': 23, 'local': 'Shenzhen'}
    
    print(type(st.index('ma')))
    print(st.index('ma'))
    print(type(l.index(2)))
    print(l.index(2))
    print(type(t.index({1, 2, 3, 4, 5})))
    print(t.index({1, 2, 3, 4, 5}))
    print(type(se.index((1, 2, 3, 4, 5))))
    print(se.index((1, 2, 3, 4, 5)))
    print(type(d.index('age')))
    print(d.index('age'))
    
    """
    运行结果:
    <class 'int'>
    5
    <class 'int'>
    1
    <class 'int'>
    5
    AttributeError: 'set' object has no attribute 'index'
    AttributeError: 'dict' object has no attribute 'index'
    """
    

    add()

    添加指定元素

    • 格式:set.add(element)
    • 返回值:None
    • 注意:只能用在set上
    # add()案例
    st = 'I am madman'
    l = [1, 2, 3, 4, 5]
    t = (1, 2, 3, 4, 5)
    se = {1, 2, 3, 4, 5}
    
    print(st.add('!'))
    print(st)
    print(l.add(6))
    print(l)
    print(t.add(6))
    print(t)
    print(se.add(6))
    print(se)
    print(se.add((7, 8, 9)))
    print(se)
    
    """
    运行结果:
    AttributeError: 'str' object has no attribute 'add'
    AttributeError: 'list' object has no attribute 'add'
    AttributeError: 'tuple' object has no attribute 'add'
    None
    {1, 2, 3, 4, 5, 6}
    None
    {1, 2, 3, 4, 5, 6, (7, 8, 9)}
    """
    

    remove()

    删除指定元素(会报错)

    • 格式:list/set.remove(element)
    • 返回值:None
    • 注意
      • 只能用在list、set上
      • 如果删除不存在的元素,会报错
    # remove()案例
    st = 'I am madman'
    l = [1, 2, 3, 1]
    t = (1, 2, 3, 1)
    se = {1, 2, 3, 4, (1, 2, 3)}
    
    print(st.remove('I'))
    print(st)
    print('*' * 20)
    
    print(l.remove(1))
    print(l)
    print(l.remove(1))
    print(l)
    print(l.remove(1))
    print(l)
    print('*' * 20)
    
    print(t.remove(1))
    print(t)
    print(t.remove(1))
    print(t)
    print(t.remove(1))
    print(t)
    print('*' * 20)
    
    print(se.remove(4)
    print(se)
    print(se.remove((1, 2, 3)))
    print(se)
    print(se.remove(4))
    print(se)
    
    """
    运行结果:
    AttributeError: 'str' object has no attribute 'remove'
    ********************
    None
    [2, 3, 1]
    None
    [2, 3]
    ValueError: list.remove(x): x not in list
    ********************
    AttributeError: 'tuple' object has no attribute 'remove'
    ********************
    None
    {1, 2, 3, (1, 2, 3)}
    None
    {1, 2, 3}
    """
    

    discard()

    删除指定元素(不报错)

    • 格式:set.discard(elemnet)
    • 返回值:None
    • 注意
      • 只能用到set上
      • 如果删除不存在的元素,不报错
    # discard()案例
    st = 'I am madman'
    l = [1, 2, 3, 1]
    t = (1, 2, 3, 1)
    se = {1, 2, 3, 4, (1, 2, 3)}
    
    print(st.remove('I'))
    print(st)
    print('*' * 20)
    
    print(l.discard(1))
    print(l)
    print('*' * 20)
    
    print(t.discard(1))
    print(t)
    print('*' * 20)
    
    print(se.discard(4))
    print(se)
    print(se.discard((1, 2, 3)))
    print(se)
    print(se.discard(4))
    print(se) 
    
    """
    运行结果:
    AttributeError: 'str' object has no attribute 'remove'
    ********************
    AttributeError: 'list' object has no attribute 'discard'
    ********************
    AttributeError: 'tuple' object has no attribute 'discard'
    ********************
    None
    {1, 2, 3, (1, 2, 3)}
    None
    {1, 2, 3}
    None
    {1, 2, 3}
    """
    

    pop()

    弹出一个元素

    • 格式
      • list:list.pop(index=-1)
      • set:set.pop()
      • dict:dict.pop(key)
    • 返回值:弹出的元素
    • 注意
      • 只能用在list、set、dict上
      • 如果list、set、dict为空,报错
      • list默认弹出最后的元素,可以用索引指定弹出的元素
      • set默认弹出最前的元素
      • dict使用pop()时一定要指定key
    # pop()案例
    st = 'I am madman'
    l = [1, 2, 3, 1, {1, 2, 3}]
    t = (1, 2, 3, 1)
    se = {1, 2, 3, 4, (1, 2, 3)}
    d = {'name': 'madman', 'age': 23, 'local': 'Shenzhen'}
    
    print(st.pop())
    print(st)
    print('*' * 20)
    
    print(l.pop(2))
    print(l)
    print(l.pop())
    print(l)
    print('*' * 20)
    
    print(t.pop())
    print(t)
    print('*' * 20)
    
    print(se.pop())
    print(se)
    print(se.pop())
    print(se)
    print('*' * 20)
    
    print(d.pop('name'))
    print(d)
    print(d.pop())
    print(d)
    
    """
    运行结果:
    AttributeError: 'str' object has no attribute 'pop'
    ********************
    3
    [1, 2, 1, {1, 2, 3}]
    {1, 2, 3}
    [1, 2, 1]
    ********************
    AttributeError: 'tuple' object has no attribute 'pop'
    ********************
    1
    {2, 3, 4, (1, 2, 3)}
    2
    {3, 4, (1, 2, 3)}
    ********************
    madman
    {'age': 23, 'local': 'Shenzhen'}
    TypeError: pop expected at least 1 arguments, got 0
    """
    
    展开全文
  • 可迭代对象Python 可迭代对象可以分为三类:迭代器(iterator): 生成器(generator)序列(list, str, tuple, set)字典(dict)# 可迭代对象for i in set(1,2,3,4):print(i)# 能用next(i) TypeError: 'set' object is ...

    可迭代对象

    Python 可迭代对象可以分为三类:

    迭代器(iterator): 生成器(generator)

    序列(list, str, tuple, set)

    字典(dict)

    # 可迭代对象

    for i in set(1,2,3,4):

    print(i)

    # 不能用next(i) TypeError: 'set' object is not an iterator

    set集合是一个可迭代对象,但不是迭代器

    迭代器

    可迭代对象需要实现__iter__方法,迭代器不仅要实现__iter__方法,还需要实现__next__方法

    迭代器是可迭代对象的一个子集,它是一个可以记住遍历的位置的对象,它与列表、元组、集合、字符串这些可迭代对象的区别就在于__next__方法的实现,其他列表、元组、集合、字符串这些可迭代对象可以通过Python内置的iter函数能很简单的转化成迭代器。

    X = [1,2,3,4,5]

    print(type(X))

    Y = iter(X)

    print(type(Y))

    print(next(Y))

    print(next(Y))

    print(next(Y))

    # 输出

    1

    2

    3

    自定义迭代器

    class Iterator(object):

    def __init__(self, array):

    self.x = array

    self.index = 0

    def __iter__(self):

    return self

    def __next__(self):

    if self.index < len(self.x):

    value = self.x[self.index]

    self.index += 1

    else:

    raise StopIteration

    return value

    it = Iterator([1,2,3,4,5])

    print(type(it))

    for i in it:

    print(i)

    # 输出

    1

    2

    3

    4

    5

    使用itertools库生成迭代器

    todo

    生成器

    生成器是迭代器的子集

    使用yield关键字构建生成器

    yield 后接单个内容

    def generator(array):

    for i in array:

    yield i

    gen = generator([1,2,3,4,5])

    print(type(gen))

    for j in gen:

    print(j)

    # 输出

    1

    2

    3

    4

    5

    使用yield from关键字构建生成器

    yield from 后接可迭代对象,但也是逐个返回

    def generator(array):

    for sub_array in array:

    yield from sub_array

    gen = generator([(1,2,3), (4,5,6,7)])

    # 输出

    1

    2

    3

    4

    5

    6

    7

    展开全文
  • 可迭代对象和迭代器

    2017-08-15 17:33:00
    可迭代对象:可作用于for循环的都是可迭代对象,包括字符串、列表、元组、字典等,数字可以for循环即不是可迭代对象 >>> from collections import Iterable >>> print(isinstance("ABC",...
  • 迭代器一定是可迭代对象,但是可迭代对象不一定是迭代器。list,truple,str这些都是可迭代对象,但是他们一定是迭代器。迭代器本身知道自己要执行多少次,所以可以理解为知道有多少个元素,每调用一次next()...
  • 公众号:pythonislover Python大数据与SQL优化笔记首先我们要知道Python迭代器与可迭代对象不是一个概念。迭代器:是访问数据集合内元素的一种方式,一般用来遍历数据,但是他能像列表一样使用下标来获取数据,也...
  • 迭代器1.什么是迭代器?依赖于索引的取值方式迭代是一个重复的过程,即每一次重复为一次迭代,并且每次迭代的结果都是下一次迭代的初始值...#可迭代对象指的是内置有.__iter__方法的对象'world'.__iter__(4,5,6)._...
  • 可迭代对象与迭代器

    2021-01-29 13:34:59
    可迭代对象: 可以用 for 循环遍历的对象都是可迭代对象。 str,list,tuple,dict,set 等都是可迭代对象。 generator (生成器 和 yield 的生成器函数) 也是可迭代对象。 判断是否可迭代 是否有内置的__iter__方法 ...
  • 迭代器迭代器(iterator...摘自维基百科也就是说迭代器类似于一个游标,卡到哪里就是哪里,可以通过这个来访问某个可迭代对象的元素;同时,也不是只有Python有这个特性。比如C++的STL中也有这个,如vector::iterator...
  • 关于可迭代对象和迭代器的关系和构建一直理解的都太深入,今天就自己来深刻扒一扒他们之间的关系! 可迭代对象(iterable): python中的可迭代对象包括list, dict, tuple, str, 用dir()函数查看他们的对象方法都会发现...
  • 可迭代的/可迭代对象

    2018-11-05 20:32:58
    可迭代的/可迭代对象 for i in 7:print(i) iterable 可迭代 整数类型 是不可迭代的 iter 迭代 iterable 可迭代的 dir函数查看一个数据类型内部含有哪些方法 两边带着双下划线的方法叫做"魔术方法",“双下...
  • 什么事可迭代对象__iter__方法的作用是让对象可以用for … in循环遍历,getitem( ...一个可迭代对象能独立进行迭代的,Python中,迭代是通过for … in来完成的。凡是可迭代对象都可以直接用for… in…循环访问,...
  • python中可迭代对象指的是什么发布时间:2020-07-20 11:19:38来源:亿速云阅读:91作者:清晨小编给大家分享一下python中可迭代对象指的是什么,相信大部分人都还怎么了解,因此分享这边文章给大家学习,希望大家...
  • python 中内置的可迭代对象有 list、tuple、set、dict 等,那么我们自己怎么定义一个可迭代对象呢?先来段代码吧import reimport reprlibRE_WORD = re.compile('\w+')class Sentence:def __init__(self, text):...
  • 但凡内置有__iter__方法的对象,都称为可迭代对象,可迭代的对象:str,list,tuple,dict,set,文件对象 二.迭代器对象 1.既内置又__next__方法的对象,执行该方法可以依赖索引取值 2.又内置有__iter__方...
  • 可迭代对象 TO 迭代器

    2019-09-27 15:13:03
    可迭代对象并不是迭代器,只是支持迭代。可被for循环遍历的对象,比如list,dict ,tuple ,string都是可迭代对象 那既然支持迭代,那要如何用迭代替换for循环呢? 内置函数 iter 帮到您 在可迭代对象外面套一个...
  • 1.可迭代对象字符串、集合、列表、字典、元组都是可迭代的对象,数字不是可迭代的,就是可以通过for循环取出元素的对象,都是可迭代对象如果查看一个变量是否为可迭代:s = {1, 2, 3, 4}print(type(s)) #print...
  • JavaScript 可迭代对象

    2020-07-16 12:22:57
    Javascript 可迭代对象 小插曲 我之前学到了对象与数组进行拼接,如果对象加 [Symbol.isConcatSpreadable]:true,对象不会当作数组处理,反之,对象的元素将会像数组中的元素一样,被复制进数组中。 正题 可迭代...
  • 1、 什么事可迭代对象、通熟来讲 就是可以做for循环的对象(如:list,tupe,dict,集合,列表生成式,字符串, 等等) 2、怎么判断一个对象式不是可迭代对象呢 可以使用 from collections import Iterable a=...
  • 文章目录一、可迭代对象是什么?二、各迭代方法的区别1. for in 迭代方法2. for..of迭代方法和foreach迭代方法三、扩展运算符的使用总结 一、可迭代对象是什么? 可迭代对象包括:Array、Set、Map、Arguments、...
  • 迭代器与可迭代对象

    2019-03-15 16:20:31
    迭代器与可迭代对象 概念 迭代器:是访问数据集合内元素的一种方式,一般用来遍历数据,但是它能像列表一样使用下标来获取数据,也就是说迭代器是能返回的。 Iterator:迭代器对象,必须要实现next魔法函数...
  • 迭代器就是可迭代对象调用iter()方法,返回了一个迭代器那么什么是可迭代对象呢?像字符串,列表,字典,元祖等这些容器可以使用for循环进行遍历依次拿到容器中的数据,我们把这样的过程称为迭代。你也可...
  • 记得在刚开始学Python的时候,看到可迭代对象(iterable)、迭代器(iterator)和生成器(generator)这三个名词时,完全懵逼了,根本就知道是啥意识。现在以自己的理解来详解下这三者的关系。一、可迭代对象(iterable)...
  • 迭代器 迭代:更新换代(重复)的过程,每次的迭代都必须基于上一次的结果 ...可迭代对象 :只有内置有__iter__方法的都叫做可迭代对象 基本数据类型中 是可迭代对象的有:str list tuple dict set 文件对象(执行内置...
  • 迭代器协议:必须实现__next__()方法,...可迭代对象:列表,字典,元素,字符串等,但可迭代对象一定是迭代器 from collections import Iterable, Iterator a = [1, 2, 3] isinstance(a, Iterable) # True isinsta
  • 迭代器一定是可迭代对象,但是可迭代对象不一定是迭代器。 list,truple,str这些都是可迭代对象,但是他们一定是迭代器。迭代器本身知道自己要执行多少次,所以可以理解为知道有多少个元素,每调用一次next...
  • 刚开始接触python的同学在各种参考书或者网上资料中经常看到迭代...python中的对象,可以分为可迭代对象,不可迭代对象。当我们说一个对象是“可迭代”的时候,这个可迭代对象会具有一些特定的特点和属性。第一,直...
  • 迭代器与可迭代对象 1、定义: 可迭代对象:大部分容器如list,...迭代器:迭代器提供了一种依赖索引取值的方式,这样可以遍历没有索引的可迭代对象,比如字典、集合、文件等等,加载这一个元素至内存中随后...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,437
精华内容 2,174
关键字:

不可迭代对象