V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
推荐学习书目
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
kzing
V2EX  ›  Python

Python 怎么优雅的实现 Ruby 的('a'..'z').to_a 操作?

  •  
  •   kzing · Jun 19, 2014 · 9738 views
    This topic created in 4341 days ago, the information mentioned may be changed or developed.
    单纯的实现从'a'到'z'的遍历不难, 但是如果要实现这样的
    输入: ('ab'..'xy').to_a

    输出: ["ab", "ac", "ad",... ... ,"xw", "xx", "xy"]

    可能就比较复杂

    有比较Pythonic的方法或者算法吗?
    Supplement 1  ·  Jun 20, 2014
    题主正在面壁反思ing...

    补充一下描述

    在Ruby中:
    ('a'..'bc').to_a 输出:

    ["a", "b", "c",... ..., "z", "aa", "ab", "ac", ... ..., "ay", "az", "ba", "bb", "bc"]

    甚至

    ('ab', 'cd').to_a 输出:

    ["ab", "ac", "ad", ... ..., "az", "ba", "bb", "bc", "bd", ... ..., "bz", "ca", "cb", "cc", "cd"]
    Supplement 2  ·  Jun 20, 2014
    题主正在面壁反思ing...

    补充一下描述

    在Ruby中:
    ('a'..'bc').to_a 输出:

    ["a", "b", "c",... ..., "z", "aa", "ab", "ac", ... ..., "ay", "az", "ba", "bb", "bc"]

    甚至

    ('ab', 'cd').to_a 输出:

    ["ab", "ac", "ad", ... ..., "az", "ba", "bb", "bc", "bd", ... ..., "bz", "ca", "cb", "cc", "cd"]
    44 replies    2020-06-16 11:50:19 +08:00
    ddzz
        2
    ddzz  
       Jun 19, 2014
    这种花拳绣腿功能是专门用来打广告的
    orancho
        3
    orancho  
       Jun 19, 2014
    笑看二楼无脑黑,懒得吵,好不好用自己心里知道
    RIcter
        4
    RIcter  
       Jun 19, 2014
    @orancho 幫你@一下>_>
    cc @ddzz
    manfay
        5
    manfay  
       Jun 19, 2014
    S1 = 'abcdefghijklmnopqrstuvwx'
    S2 = 'bcdefghijklmnopqrstuvwxy'
    L = [a+b for a in S1 for b in S2]
    orancho
        6
    orancho  
       Jun 19, 2014
    @RIcter 不用,已经blocked了
    kzing
        7
    kzing  
    OP
       Jun 20, 2014
    @RIcter 这个模块大家都会, 但是你贴这个链接似乎对我没有什么帮助 :)
    kzing
        8
    kzing  
    OP
       Jun 20, 2014
    @ddzz :) 这么看来, Ruby中很多我认为很酷的功能都是花拳绣腿啊
    kzing
        9
    kzing  
    OP
       Jun 20, 2014
    @manfay 不错唉, 提供了一个思路. 谢谢.
    RIcter
        10
    RIcter  
       Jun 20, 2014
    @kzinglzy 我发的链接稍微看一下里面的内容啊,有实现的
    kzing
        11
    kzing  
    OP
       Jun 20, 2014
    @RIcter 不会吧= =! 自认已经看过很多遍Itertools模块了, 指点一下?
    incompatible
        12
    incompatible  
       Jun 20, 2014
    卧槽 搞java和groovy的完全看不懂你们在说什么

    到底什么场景下会需要遍历'ab'-'xy'这些玩意儿??
    kzing
        13
    kzing  
    OP
       Jun 20, 2014
    @incompatible 也许可以类比一下Linux? 比如要生成某些连续的文件; 又比如做爬虫时遍历一连串有规律的渐变的URL? 再比如做算法题的时候需要一个映射数字到字母组合的映射? 懂得少, 没想出必须要用到的地方. 但我觉得存在即意义, 如果一点用都没有的话, 我也就不会从Ruby文档看到这个了:)

    我的本意是交流这个问题的Pythonic实现. 谢谢.
    mulog
        14
    mulog  
       Jun 20, 2014
    s = string.ascii_lowercase
    result = [t[0]+t[1] for t in itertools.product(s, repeat=2)]
    # or
    result = [a+b for a in s for b in s]

    其实没太看懂你到底想输出啥,既然有"xx"为啥没有"aa"
    总之大概这个意思
    kzing
        15
    kzing  
    OP
       Jun 20, 2014
    @mulog 谢谢你, 这是Ruby的一个用法, 我也刚学, 觉得这样用很酷就拿过来玩一下了. 先睡觉了.
    orzfly
        16
    orzfly  
       Jun 20, 2014   ❤️ 1
    Ruby 里也用不上 ('ab'..'xy').to_a 啊,用 [*'aa'..'zz'] 就好了~\(≧▽≦)/~啦啦啦
    glasslion
        17
    glasslion  
       Jun 20, 2014
    数学老师死的早系列
    mikale
        18
    mikale  
       Jun 20, 2014
    [x+y for x in map(chr,range(97,122)) for y in map(chr,range(97,122))]
    dreampuf
        19
    dreampuf  
       Jun 20, 2014   ❤️ 1
    os.popen("echo {a..x}{b..y}").read().split()

    [a+b for a, b in itertools.product(string.lowercase[:-2], string.lowercase[1:-1])]

    这种比较会不会只能证明 Because I can.
    Pythonic的楼上已经有了,规规矩矩的。总之要实现语言不支持的特性时,import this
    pandada8
        20
    pandada8  
       Jun 20, 2014   ❤️ 1
    import itertools
    import string
    ("".join(i) for i in itertools.product(string.ascii_lowercase, repeat=2))
    s51431980
        21
    s51431980  
       Jun 20, 2014
    当大牛花了半小时想出两行pythonic代码的时候,实习生用几分钟写了四行简明但看起来不pythonic的代码实现了相同的功能
    shyrock
        22
    shyrock  
       Jun 20, 2014
    就代码易读易理解来说,我觉得5楼的最好。而且我认为这就是优雅。
    Kabie
        23
    Kabie  
       Jun 20, 2014
    很可惜上面所有直接遍历的实现都是错的…………至少……和Ruby里的行为不同……

    这个还是朴实的做个生成器吧。。。

    当然……ruby里的这个字符串succ的行为有很多特例。。。唯一能正确实现的办法……恐怕只能是把 http://www.ruby-doc.org/core-2.1.2/String.html#method-i-succ 的代码翻译成Python了……
    glasslion
        24
    glasslion  
       Jun 20, 2014
    @shyrock 那么'asfedfger'..'rghrehtrh' 也用多重循环来写?
    generic
        25
    generic  
       Jun 20, 2014 via Android
    @Kabie 这个例子告诉我们,在X语言社区里问“Y语言的某功能在X语言里怎么实现”,最好先说明其在Y语言里的行为。
    wangtai
        26
    wangtai  
       Jun 20, 2014
    小弟不懂Ruby,请问各位Ruby大神,这种写法一般在什么场景下使用啊
    est
        27
    est  
       Jun 20, 2014   ❤️ 1
    哈哈,LZ这个卡位比较好。几个python解结果和LZ的结果不一样。
    kzing
        28
    kzing  
    OP
       Jun 20, 2014
    @generic 原来V2EX已经默认位Ptyhon社区了吗= =!
    kzing
        30
    kzing  
    OP
       Jun 20, 2014
    @generic 这不是更惨吗...那我应该会有这样的回复" 这是Ruby的板块, 你提问Python的问题?"
    hahastudio
        31
    hahastudio  
       Jun 20, 2014   ❤️ 1
    关键是LZ太欺负人= =
    不给清楚里面怎么迭代的= =
    哪知道"ax"后面是 "ay", "az", "ba", "bb" 啊= =
    这应该是从aa到zz里面掐了ab到xy这一段= =

    我给一个比较Pythonic的方案,在14L @mulog 的方案上稍微改一下就可以
    反正没有缩进,就直接在这里贴了
    用了''.join(t),这样你想涨长就改repeat和if里的边界就好了= =

    import string
    import itertools

    s = string.ascii_lowercase
    result = [ ''.join(t) for t in itertools.product(s, repeat=2) if "ab" <= ''.join(t) <= "xy" ]
    yuankui
        32
    yuankui  
       Jun 20, 2014
    写个函数吧。。
    to_a('aa','zz') rets ['aa',...,'zz']
    shyrock
        33
    shyrock  
       Jun 20, 2014
    @glasslion 不懂ruby,'asfedfger'..'rghrehtrh' 出怎样的结果?
    fwee
        34
    fwee  
       Jun 20, 2014
    @shyrock 取下一个值会调用next方法,很类似haskell,一般都是1..9这种数字范围
    binux
        35
    binux  
       Jun 20, 2014
    这个返回里面有 az 吗?如果有 az 为什么会有,不是只到 xy 吗?那有 aA,aZ 吗?
    不理解这个函数是干嘛的。
    manfay
        36
    manfay  
       Jun 20, 2014
    如果返回里有 az ,那么这个函数就是 Python 想要避免的 implicit.

    Explicit is better than implicit.
    blacktulip
        37
    blacktulip  
       Jun 20, 2014 via iPhone
    此贴好好玩,you are not your programming language. 不用觉得伤自尊。
    Kabie
        38
    Kabie  
       Jun 20, 2014
    https://github.com/topazproject/topaz/blob/master/topaz/objects/stringobject.py#L274

    String#succ 的 python 版。。。。。。其实和 C 没啥区别了。。。
    reusFork
        39
    reusFork  
       Jun 20, 2014
    jinyiming321
        40
    jinyiming321  
       Jun 20, 2014
    ruby这个是抄perl的。。。
    est
        41
    est  
       Jun 20, 2014   ❤️ 2
    @hahastudio 同意。为什么只遍历到a-z,为什么不会遍历大写A-Z?

    把LZ的语句改一下:

    ('Ww'..'xy').to_a

    那么请问Ruby为何不W X Y Z a b c ... w x 这样遍历?为什么不会xy结尾停止而是Zz停止?

    ('[a'..'xy').to_a

    为什么又只会遍历 [ 开头的,但是不会结束于[y而是[z???

    所以总结一句话:滥用语言特性,隐蔽黑魔法。LZ的“妙用”只是一个巧合。
    hahastudio
        42
    hahastudio  
       Jun 20, 2014
    @est 对,ruby的这块感觉很莫名其妙的
    大写..小写会在Z处断片

    再加几个

    >> ("aa".."ZZ").to_a
    => []
    >> ('[ab'..'xy').to_a
    => ["[ab"]
    >> ("01".."10").to_a
    => ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10"]
    >> ("a01".."z10").to_a
    => 你会看到"a99", "b00"
    >> ("01a".."10b").to_a
    => 你会看到"01z", "02a", "02b", "02c",最后是"09z", "10a", "10b"

    这种跟期待不一样的返回值还是有点伤人的

    嘛,不过是个语言都有一些坑,Python也有
    所以优雅只是相对的,对不用的语言,优雅的地方有时不一样;对同一个语言的同一种语法,有时优雅,有时就不怎么好看了
    mikale
        43
    mikale  
       Jun 21, 2014
    方法给了,还要一样,真是矫情,来一个跟题目一样的。

    [x+y for x in map(chr,range(97,121)) for y in map(chr,range(98,122))]
    yykrlc
        44
    yykrlc  
       Jun 16, 2020
    ruby 的 x = {"a": 1 "b": 2}
    y = 'b'
    > x[y]
    => nil
    > x[:b]
    => 2
    怎么解我不能传值:b 吧
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   967 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 79ms · UTC 22:17 · PVG 06:17 · LAX 15:17 · JFK 18:17
    ♥ Do have faith in what you're doing.