V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
qdzzyb
V2EX  ›  Python

今天笔试遇到的一道题,请问还有其他做法吗?

  •  
  •   qdzzyb · 2016-01-20 20:53:56 +08:00 · 5211 次点击
    这是一个创建于 3236 天前的主题,其中的信息可能已经有所发展或是发生改变。

    请实现函数 new_counter ,使得调用结果如下:

    c1 = new_counter(10)
    c2 = new_counter(20)
    print c1(), c2(), c1(), c2()
    
    outputs :
    11 21 12 22
    

    我的想法:

    def new_counter(n):
    
        class Counter(object):
            def __init__(self, num):
                self.num =num
    
            def __call__(self):
                self.num += 1
                return self.num
    
        return Counter(n)
    

    结束以后才想出来的,觉得比较麻烦,还有更简洁的方法吗?
    谢谢~

    第 1 条附言  ·  2016-01-20 21:39:20 +08:00

    Python3

    def new_counter(num):
        count = num
        def counter():
            nonlocal count
            count += 1
            return count
        return counter
    

    Python2

    def new_counter(num):
        count = [num]
        def counter():
            count[0] += 1
            return count[0]
        return counter
    
    第 2 条附言  ·  2016-01-20 21:41:52 +08:00
    看着像装饰器呢~
    30 条回复    2016-01-22 18:18:58 +08:00
    jellyshen
        1
    jellyshen  
       2016-01-20 21:14:04 +08:00
    ```python
    def new_count(n):
    print(n)
    def f():
    print(n+1)
    return f
    ```
    函数 f 里不能影响变量 n 的状态,还请大神们指教。
    deangl
        2
    deangl  
       2016-01-20 21:15:37 +08:00
    def new_counter(init_val):
    _counter = [init_val, ]
    def add1():
    _counter[0] += 1
    return _counter[0]
    return add1
    zhangchioulin
        3
    zhangchioulin  
       2016-01-20 21:16:43 +08:00
    LZ 是面试的什么?
    deangl
        4
    deangl  
       2016-01-20 21:16:50 +08:00
    ```
    def new_counter(init_val):
    _counter = [init_val, ]
    def add1():
    _counter[0] += 1
    return _counter[0]
    return add1
    ```
    deangl
        5
    deangl  
       2016-01-20 21:18:39 +08:00
    啊,求教怎么发贴带格式,怎么删自己的贴?
    jellyshen
        6
    jellyshen  
       2016-01-20 21:18:50 +08:00
    问个问题,怎么在 V2EX 的回复里面排版代码?

    ```python
    def new_count(n):
    print(n)
    def f():
    print(n+1)
    return f
    ```
    zhangchioulin
        7
    zhangchioulin  
       2016-01-20 21:19:58 +08:00
    @deangl 这个...哥你用的什么语言?为什么都 return 了还能执行?
    lxy42
        8
    lxy42  
       2016-01-20 21:21:05 +08:00
    不会是搜狐吧
    lxy42
        9
    lxy42  
       2016-01-20 21:21:26 +08:00   ❤️ 1
    用闭包就行了
    deangl
        10
    deangl  
       2016-01-20 21:23:12 +08:00   ❤️ 1
    @zhangchioulin 我打不出缩进。。。。
    这个意思:

    def new_counter(init_val):
    ...._counter = [init_val, ]
    ....def add1():
    ........_counter[0] += 1
    ........return _counter[0]
    ....return add1
    tkpc
        11
    tkpc  
       2016-01-20 21:35:58 +08:00   ❤️ 5
    new_counter = lambda n : (x+n for x in xrange(sys.maxint)).next
    fghzpqm
        12
    fghzpqm  
       2016-01-20 22:07:02 +08:00 via iPad
    import itertools
    new_counter = itertools.count
    swirling
        13
    swirling  
       2016-01-20 22:18:09 +08:00 via iPhone
    high order function ,这时候你就和面试官聊聊函数式什么就好了。
    dapang1221
        14
    dapang1221  
       2016-01-20 22:26:59 +08:00
    python 生成器?用 yield 传出来就好了,不要用 return ……但是调用起来又得用 next 了。。。
    def counter(n):
    ....while True:
    ........n=(yield n+1)
    snailsir
        15
    snailsir  
       2016-01-20 22:34:11 +08:00 via iPhone   ❤️ 1
    闭包
    mengzhuo
        16
    mengzhuo  
       2016-01-20 22:34:27 +08:00   ❤️ 1
    我来上个优雅点的吧:
    def new_counter(i):
    ....def c():
    ........c.var += 1
    ........return c.var
    ....c.var = i
    ....return c


    c10 = new_counter(10)
    c20 = new_counter(20)

    print c10(), c20(), c10(), c20() #11, 21, 12, 22
    airqj
        17
    airqj  
       2016-01-20 23:26:35 +08:00 via Android
    记不清实现了
    应该是闭包
    ChiangDi
        18
    ChiangDi  
       2016-01-21 01:52:03 +08:00 via Android
    这个是最简单的闭包应用啊, Python 不熟,随便用 js 码个
    function new_count(n) {
    return function() {
    n ++
    console.log(n)
    }

    还有比这个更简单的实现吗?
    elvba
        19
    elvba  
       2016-01-21 02:40:25 +08:00
    function new_counter($t) { return function () use (&$t) { return $t += 1; }; }
    SpicyCat
        20
    SpicyCat  
       2016-01-21 09:05:40 +08:00   ❤️ 1
    @ChiangDi @airqj @dapang1221 @deangl @elvba @fghzpqm @jellyshen @lxy42 @mengzhuo @qdzzyb 楼上所有,友情提示,贴代码可以用 github 的 gist ,参考此贴: https://www.v2ex.com/t/130567
    master13
        21
    master13  
       2016-01-21 11:22:57 +08:00   ❤️ 1
    感觉做一个生成器,或者 yield 把……
    cppgohan
        22
    cppgohan  
       2016-01-21 12:04:35 +08:00
    用 itertools 偷懒可以吗?

    ```
    def new_counter(c):
    counter = itertools.count(c)
    def f():
    return counter.next()
    return f;
    ```

    ```
    class new_counter(itertools.count):
    def __init__(self, *args, **kwargs):
    super(new_counter, self).__init__(*args, **kwargs)
    def __call__(self):
    return self.next()
    ```
    cppgohan
        23
    cppgohan  
       2016-01-21 12:07:18 +08:00   ❤️ 1
    ttycode
        24
    ttycode  
       2016-01-21 12:45:21 +08:00 via Android
    闭包,或者匿名函数
    motopig
        25
    motopig  
       2016-01-21 13:29:08 +08:00
    ``` php
    function counter($num)
    {
    return function () use (&$num) {
    return ++$num."<br>";
    };
    }
    $c1 = counter(10);
    $c2 = counter(20);
    echo $c1();
    echo $c2();
    echo $c1();
    echo $c2();

    ```
    youkochan
        26
    youkochan  
       2016-01-21 15:38:29 +08:00   ❤️ 1
    def new_counter(_num):
    def foo():
    num = _num
    while True:
    num += 1
    yield num
    a = foo()
    return a.next

    c1 = new_counter(10)
    c2 = new_counter(20)

    print c1(), c2(), c1(), c2()
    shajiquan
        27
    shajiquan  
       2016-01-21 17:04:26 +08:00   ❤️ 1
    我觉得楼主提出的 class 方式就挺好的,清晰直观,不用理会变量的作用域带来的困扰。#16 楼的方法挺好玩的。
    qiu0130
        28
    qiu0130  
       2016-01-21 22:00:03 +08:00
    C pa pa 重载()运算符.
    necomancer
        29
    necomancer  
       2016-01-22 18:14:41 +08:00   ❤️ 2
    ```python3
    def new_counter(m):
    ....def counter(m):
    ........while 1:
    ............m +=1
    ............yield m
    ....return counter(m).__next__

    c1 = new_counter(10)
    c2 = new_counter(20)
    print(c1(), c2(), c1(), c2())
    ```
    没 16 楼的简洁……
    necomancer
        30
    necomancer  
       2016-01-22 18:18:58 +08:00
    啊……原来 26 楼已经是这个办法了……
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2920 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 02:40 · PVG 10:40 · LAX 18:40 · JFK 21:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.