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
Cursive
V2EX  ›  Python

刚开始学 Python,遇到个问题搞不懂,求指点下

  •  
  •   Cursive · 2016-09-01 23:53:33 +08:00 · 4738 次点击
    这是一个创建于 2786 天前的主题,其中的信息可能已经有所发展或是发生改变。

    字符串转数字的函数:

    from functools import reduce
        def str2int(s): 
            def fn(x, y): 
                return x * 10 + y 
            def char2num(s): 
                return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
            return reduce(fn, map(char2num, s))
    

    {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]

    如果的 s 是 '1' , '2' 这种单个字符,还能理解,这是取词典的键值 可是如果 s 是 '1234' , '1990' 这种的多个字符的字符串,就搞不懂了

    求指点下

    31 条回复    2016-09-19 13:48:42 +08:00
    Cursive
        1
    Cursive  
    OP
       2016-09-01 23:54:48 +08:00
    晕,不会贴代码...
    Cursive
        2
    Cursive  
    OP
       2016-09-01 23:58:55 +08:00
    @Cursive 弄错符号了...
    kely
        3
    kely  
       2016-09-02 00:05:15 +08:00 via Android
    是一个字符一个字符迭代的
    sherlocktheplant
        4
    sherlocktheplant  
       2016-09-02 00:13:29 +08:00
    我又来半桶水了 这里 map 是把字符串中每个字符遍历一遍 对每个字符做一次 char2num 操作 最后把每次 char2num 操作的结果全部放到同一个数组里返回
    然后作为参数传给 reduce
    recude 又把每个值依次乘以 10 再加上去 还原成对应的整数
    prondtoo
        5
    prondtoo  
       2016-09-02 00:39:02 +08:00
    同半桶水,例如输入的是 12345 , map(char2num, s)以后,得出的就是[1,2,3,4,5]
    最后就 reduce(lambda x,y:x*10+y,[1,2,3,4,5])
    Lonely
        6
    Lonely  
       2016-09-02 00:42:17 +08:00 via Android
    你不要把两个 s 搞混了啊
    prondtoo
        7
    prondtoo  
       2016-09-02 00:42:55 +08:00   ❤️ 1
    最后就( 1*10+2 )*10+3 )*10+4 )*10+5 ))
    myjiayan
        8
    myjiayan  
       2016-09-02 00:44:55 +08:00   ❤️ 1
    换个写法 str2int = lambda s:sum(int(v)*10**i for i, v in enumerate(s[::-1]))
    kamen
        9
    kamen  
       2016-09-02 00:47:24 +08:00 via Android
    @prondtoo 你的思路完全正确,虽然我还没看楼主的代码
    kamen
        10
    kamen  
       2016-09-02 00:48:33 +08:00 via Android
    map 和 reduce 是神器,楼主要多用,多看
    eloah
        11
    eloah  
       2016-09-02 01:32:48 +08:00   ❤️ 1
    因为 map()是对一个 iterable 的对象的 item 进行操作的,而 string 就是可 iterable 的,其中每一个字符一个 item.
    其实理解成 C 中的 char[]这样就好理解了
    markx
        12
    markx  
       2016-09-02 01:49:11 +08:00
    关键是 map 。
    Allianzcortex
        13
    Allianzcortex  
       2016-09-02 07:05:02 +08:00 via iPhone
    原理不难,函数式编程范畴,但==,为什么 char2num 不直接用 int()。。
    Cursive
        14
    Cursive  
    OP
       2016-09-02 07:19:37 +08:00
    @Lonely 就是卡到这里了, char2num(s) 的参数 s 和 return 返回中的 [s] ,在这里绕不过弯...卡死了
    Cursive
        15
    Cursive  
    OP
       2016-09-02 07:37:06 +08:00
    重新看了一遍 map 函数,大概懂了,多谢各位了~
    aeshfawre
        16
    aeshfawre  
       2016-09-02 07:54:50 +08:00
    搞这么复杂,这种写法对比 int 转换有啥优点呢?
    Allianzcortex
        17
    Allianzcortex  
       2016-09-02 09:00:32 +08:00
    @myjiayan 有点厉害!!
    hitmanx
        18
    hitmanx  
       2016-09-02 09:56:20 +08:00
    @Allianzcortex 你再想想
    Cursive
        19
    Cursive  
    OP
       2016-09-02 09:58:17 +08:00
    @aeshfawre 不是复杂不复杂的问题。在学 Python ,这是一个例子中的代码,之前没看这段代码的作用
    hitmanx
        20
    hitmanx  
       2016-09-02 10:02:27 +08:00
    @Allianzcortex 不好意思,试了一下,是我想错了。用 int 在 python 里是成立的,在 c 里是不行的,等于是把 ascii(char)转为(int)
    Allianzcortex
        21
    Allianzcortex  
       2016-09-02 10:18:08 +08:00
    @hitmanx @Cursive str2int = lambda s: reduce((lambda x, y:x * 10 + y), map(int, s))
    sudoz
        22
    sudoz  
       2016-09-02 10:24:29 +08:00
    看来是廖雪峰的教程
    dongfang
        23
    dongfang  
       2016-09-02 12:48:42 +08:00
    第一,字符串是序列
    第二, map(function,sequence)。注意到 map 要求第二个参数主要是序列就可以了。 map 会吧 function 作用到 sequence 的每一元素上。也就是 fn 会作用到字符串 s 的每一个字符上,并且返回一个 list
    hanbaobao2005
        24
    hanbaobao2005  
       2016-09-02 13:03:05 +08:00
    @Cursive 取 key ,为哈绕不过? 就相当于从字典里取值,字典的 key 就是 s ,值是 s 对应的 int 值
    Cursive
        25
    Cursive  
    OP
       2016-09-02 14:37:34 +08:00
    @sudoz 这都能看出来吗?


    @hanbaobao2005 刚开始以为函数中的参数 s 是一样的,就短路了
    chushu10
        26
    chushu10  
       2016-09-02 14:44:19 +08:00
    注意这一句:

    ```
    map(char2num, s)
    ```

    这是 map 函数将字符串 s (例如'1234')的每一个字符都交给 char2num 函数转换,这不就是 map 函数的作用吗?

    而 char2num 函数接收一个字符,返回一个数字,最后交由 reduce 函数把转换后的一个个数字组合成整数
    necomancer
        27
    necomancer  
       2016-09-02 22:48:33 +08:00
    虽然没懂为什么不直接 int('1234') 完事。但是附上递归版的:

    ```
    def str2num(s):
    if not s:
    return 0
    return 10 * str2num(s[:-1]) + {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s[-1]]
    ```
    necomancer
        28
    necomancer  
       2016-09-02 22:49:40 +08:00
    为什么没缩进……

    def str2num(s):
    ....if not s:
    ........return 0
    ....return 10 * str2num(s[:-1]) + {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s[-1]]

    只好人工缩进了
    bombless
        29
    bombless  
       2016-09-03 11:03:20 +08:00
    如果不能脑补局部化的代码可以拿张纸遮住无关的, 233
    另外初学就看 reduce 这样的方式工作的代码好么 233 ,感觉不懂编程的人初学直接看还好点,夹生的米就不容易煮熟了
    necomancer
        30
    necomancer  
       2016-09-03 15:22:17 +08:00
    kittygirl0070
        31
    kittygirl0070  
       2016-09-19 13:48:42 +08:00
    reduce 不需要了,直接用 sum 就可以了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2796 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 12:00 · PVG 20:00 · LAX 05:00 · JFK 08:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.