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

Python power set 求解,看不出 bug

  •  
  •   abcyuxue123 ·
    KrisYu · 2016-07-27 05:43:08 +08:00 · 2290 次点击
    这是一个创建于 2837 天前的主题,其中的信息可能已经有所发展或是发生改变。

    求一个 list 的所有 power set

    比如: nums = [1,2,3]

    答案:

    [
      [3],
      [1],
      [2],
      [1,2,3],
      [1,3],
      [2,3],
      [1,2],
      []
    ]
    

    我的代码,有错,要 run forever

    def subsets(nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        results = [[]]
        for num in nums:
            for result in results:
                results.extend([result + [num]])
        return results
     
    

    正确代码:

    def subsets(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        results = [[]]
        for num in nums:
            results.extend([result + [num] for result in results])
        return results
    

    可是 why ? 求高人解答一下

    5 条回复    2016-07-27 21:34:36 +08:00
    Valyrian
        1
    Valyrian  
       2016-07-27 05:45:32 +08:00
    for result in results:
    results.extend([result + [num]])

    results 每次都变多一个。。 for 永远没法到头
    SayHaHa
        2
    SayHaHa  
       2016-07-27 07:26:39 +08:00 via Android
    .不要在循环里对循环的对象做增添或删除操作
    yelite
        3
    yelite  
       2016-07-27 07:36:19 +08:00
    for result in results[:]:

    把 results 复制一份再循环就没问题了

    对 list 循环的过程,可以看作是首先由 list 生成了 iterator ,然后不断调用 __next__ 方法取得下一个值。 iterator 会持有对 list 的引用和当前的 index 。所以在循环过程中对原始的 list 作改动会产生各种奇怪的效果。

    In[2]: nums = [1,2,3,4]
    In[3]: i = iter(nums)
    In[4]: i
    Out[4]: <list_iterator at 0x10c4b7e80>
    In[5]: next(i)
    Out[5]: 1
    In[6]: nums.pop(0)
    Out[6]: 1
    In[7]: next(i)
    Out[7]: 3
    oclock
        4
    oclock  
       2016-07-27 08:38:10 +08:00
    内层 for 在遍历 results 的同时又在修改 results ,这是常见的应该避免的情况

    按楼主的双 for 循环可以这么写

    results = []
    for n in nums:
    results.extend([s[:] + [n] for s in results])
    results.append([n])
    results.append([])
    return results
    abcyuxue123
        5
    abcyuxue123  
    OP
       2016-07-27 21:34:36 +08:00
    谢谢大家,懂了,因为 iterator 用在改变的 list 上

    会再避免出现类似的问题
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2189 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 05:20 · PVG 13:20 · LAX 22:20 · JFK 01:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.