V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
crella
V2EX  ›  问与答

写错 Python 部分代码,结果让我想不明白

  •  
  •   crella · 2020-10-02 15:05:18 +08:00 · 1410 次点击
    这是一个创建于 1307 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问题比较难描述。我是新手,本来我是用 Ruby 写全排列算法生成器的,然后想看 Python 怎么写。我不懂 Python,所以看别人怎么用 yield 也就随便用。问题出在我写错的最后一句:print(','.join(str(o))),打印的结果我实在看不懂,或许是我不懂 yield 的流程。是我的 yield 哪里写错了吗?

    # 生成数组[1,2,3,4]的全部元素的全排列
    def scan(src, m, n):
      if (m == n):
        yield src
      else:
        for i in range(m, (n+1)):
          # 交换
          tmp = src[m]
          src[m] = src[i]
          src[i] = tmp
          
          # 递归
          for _ in scan(src, (m+1), n):
            yield _
          
          # 恢复交换前
          tmp = src[m]
          src[m] = src[i]
          src[i] = tmp   
      
    
    
    def perm_core(src):
      n = len(src) - 1
      for _ in scan(src, 0, n):
        yield _
    
    
    # main
    list = [i for i in range(1, 5)]
    for o in perm_core(list):
      # ~ w = [str(y) for y in o]
      # ~ print (','.join(w)) # 正确代码
      
      print(','.join(str(o))) # 错误代码
    
    

    打印结果

    img

    6 条回复    2020-10-02 17:28:54 +08:00
    binux
        1
    binux  
       2020-10-02 15:13:03 +08:00 via Android   ❤️ 1
    你不懂 join
    Pagliacii
        2
    Pagliacii  
       2020-10-02 15:19:09 +08:00   ❤️ 1
    https://sm.ms/image/G54yMndwJrOcEgN

    问题在于你直接将列表作为参数传给了 str,结果就如图所示了
    superrichman
        3
    superrichman  
       2020-10-02 16:02:43 +08:00 via iPhone   ❤️ 2
    你的问题楼上说了,传给 str 的参数有问题,你需要对列表里每一个元素转 str 而不是整个列表转 str 。

    其实需要字符串的列表在列表生成的时候就可以转了,比如把 i 改成 str(i)
    list = [str(i) for i in range(1, 5)]
    不过变量不要取名为 list,这会和 python 内置的 list 函数冲突,可能会引起其它问题。

    python 内置模块有排列组合的功能, 可以去搜索关键字 itertools permutation combination,内置的实现一般运行效率会比自己写的高

    python 交换变量的值,可以不用自己声明临时变量,直接
    a, b = b, a
    完成交换
    Pagliacii
        4
    Pagliacii  
       2020-10-02 16:27:55 +08:00
    实际上你用递归来写的话,可以写得更简短一点,就像这样:

    https://i.loli.net/2020/10/02/idFkXWS6LjNgr1v.png
    Pagliacii
        5
    Pagliacii  
       2020-10-02 16:36:33 +08:00
    @Pagliacii #4 我写的这段代码没考虑空列表的情况,可以将 `len(l) == 1` 改成 `len(l) < 2`。

    另外最里层循环体可以简单地用 `yield [i] + others` 来代替
    crella
        6
    crella  
    OP
       2020-10-02 17:28:54 +08:00
    想明白了,Python 里 str1.join(str2) 表示 str2 的每个字符用 str1 相连
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2324 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 03:24 · PVG 11:24 · LAX 20:24 · JFK 23:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.