python 生成器的唯一缺点 & enumerate被遗忘的start & 突然好奇in

1、
啊,在逛知乎的时候,遇到帖子(python生成器到底有什么优点?): https://www.zhihu.com/question/24807364
之前倒是知道优点,1、惰性加载,消耗内存少,2、用yield写代码后精简。
但是缺点倒是毫无印象:只能遍历一次。
接下来就用demo来看看是不是只能遍历一次吧。
demo:计算一个string里面的单词出现位置。
# -*- coding:utf-8 -*-
def index_words(text):
    result = []
    if text:
        result.append(0)

    for index, letter in enumerate(text,1):  # 表示从1开始计数
        if letter == ' ':
            result.append(index)
    return result


def index_words_with_generator(text):
    if text:
        yield 0
    for index, letter in enumerate(text, 1):
        if letter == ' ':
            yield index


text = "You are so nice... Hello world!"

print "index_words =", index_words(text)
print "index_words_with_generator =", [v for v in index_words_with_generator(text)]


# 唯一的缺点:生成器只能遍历一次
a = index_words_with_generator(text)
b = sum(a)
print 'sum(a) == ', b
print 'start!'
for i in a:
    print 'can not see this print...'
print 'end!’

结果:
index_words = [0, 4, 8, 11, 19, 25]
index_words_with_generator = [0, 4, 8, 11, 19, 25]
sum(a) ==  67
start!
end!

2、
其实比起生成器,我更在乎这个: enumerate(text,1)
这个enumerate我也经常用于计算list中的index,但是还是第一次看到后来还能带个参数1。。
查看官方文档:
class enumerate(object):
    """
    enumerate(iterable[, start]) -> iterator for index, value of iterable
    
    Return an enumerate object.  iterable must be another object that supports
    iteration.  The enumerate object yields pairs containing a count (from
    start, which defaults to zero) and a value yielded by the iterable argument.
    enumerate is useful for obtaining an indexed list:
        (0, seq[0]), (1, seq[1]), (2, seq[2]), ...
    """
start表示计数开始位置,可怕,被教育了。

3、
突然想知道,in 配合生成器,到底做了什么鬼操作了。
print 0 in index_words_with_generator(text)
文件名4.py
# -*- coding:utf-8 -*-
def index_words_with_generator(text):
    if text:
        yield 0
    for index, letter in enumerate(text, 1):
        if letter == ' ':
            yield index


text = "You are so nice... Hello world!"

a = 19 in index_words_with_generator(text)    ## 12行
print a      ## 13行
然后python -m dis 4.py:
(myapp_venv) ➜  myApp git:(v1.7_dev) ✗ python -m dis 4.py
  2           0 LOAD_CONST               0 (<code object index_words_with_generator at 0x108c6cd30, file "4.py", line 2>)
              3 MAKE_FUNCTION            0
              6 STORE_NAME               0 (index_words_with_generator)

10           9 LOAD_CONST               1 ('You are so nice... Hello world!')
             12 STORE_NAME               1 (text)

12          15 LOAD_CONST               2 (19)
             18 LOAD_NAME                0 (index_words_with_generator)
             21 LOAD_NAME                1 (text)
             24 CALL_FUNCTION            1
             27 COMPARE_OP               6 (in)
             30 STORE_NAME               2 (a)

13          33 LOAD_NAME                2 (a)
             36 PRINT_ITEM          
             37 PRINT_NEWLINE       
             38 LOAD_CONST               3 (None)
             41 RETURN_VALUE        
可惜看不出什么鬼:
12   15 LOAD_CONST               2 (19)   # 19进栈
     18 LOAD_NAME                0 (index_words_with_generator)  # 函数名进栈
     21 LOAD_NAME                1 (text)  #函数参数进栈
     24 CALL_FUNCTION            1        #调用index_words_with_generator(text)
     27 COMPARE_OP               6 (in)   # 判读in不in
     30 STORE_NAME               2 (a)    # 结果保存到a
文档找不到。其实这个应该要涉及比较底层的东东,估计要去看C语言中对于in的实现。
找到这么一段话:

38 down vote accepted
It depends on what  next  is.
If it's a string (as in your example), then  in  checks for substrings.
>>> "in" in "indigo"
True
>>> "in" in "violet"
False
>>> "0" in "10"
True
>>> "1" in "10"
True
If it's a different kind of iterable (list, tuple, dictionary...), then  in  checks for membership.
不过自己做的测试是,它会遍历直到找到这个19为止,返回True。如果遍历完后依旧找不到19,就False。
有趣的in。 

以上

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值