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

提一个关于列表内部遍历的初级问题,望慷慨相助

  •  
  •   niqzhao · 2015-12-17 10:34:11 +08:00 · 2137 次点击
    这是一个创建于 3257 天前的主题,其中的信息可能已经有所发展或是发生改变。
    无编程背景新手初学 python, 在 Codewars 上面做题,遇到一个题目要求:将传入的任意名字列表里面四个字母长的名字列表返回,我想的办法是这样的:
    def friend(x):
    for value in x:
    if len(value) != 4:
    x.remove(value)
    return x

    然而传入测试列表['Ryan', '123', 'CoolMan']时,结果是这样:

    friend(['Ryan', '123', 'CoolMan'])
    ['Ryan', 'CoolMan']

    '123'被删掉了,'Coolman'没按我想的被删掉,请问原因是什么?

    P.S. 解决这个问题本身的办法已经知道了,比如把四个字长的值放到新列表里,用 filter()等,这里希望知道该错误背后的原理。另外这种初级问题提在这合适吗,有更合适的地方请指条明路,不胜感激。
    13 条回复    2015-12-17 18:26:00 +08:00
    imn1
        1
    imn1  
       2015-12-17 10:42:44 +08:00   ❤️ 1
    原则,遍历时尽量不要改变原列表
    应该新建列表,符合的扔过去,遍历完元列表没用就删掉,内存回收
    niqzhao
        2
    niqzhao  
    OP
       2015-12-17 10:45:12 +08:00
    @imn1 感谢回复
    jmc891205
        3
    jmc891205  
       2015-12-17 10:50:41 +08:00   ❤️ 1
    你把'123'删掉之后,'CoolMan'挪到了第 2 个元素的位置,但是迭代器已经到了第 3 个元素, for 循环就退出了。

    如 @imn1 所说,遍历时不要改变正在遍历的容器,否则遍地是坑。
    imn1
        4
    imn1  
       2015-12-17 10:57:48 +08:00
    呃,你问原理啊,没看清
    没看过源代码,说不清
    猜想跟 @jmc891205 说的,因为列表是可遍历对象,感觉像指针一样指示 index ,不妨用 enumerate()测试看看

    PS:问原理的话,不算初级问题了,至少我这初级就不懂, 2333
    baichi
        5
    baichi  
       2015-12-17 13:42:41 +08:00 via iPad
    http://www.pythontutor.com 楼主你可能会需要这个工具
    gejigeji
        6
    gejigeji  
       2015-12-17 14:15:48 +08:00
    你要是在 C++这么写就会编译不过
    bramblex
        7
    bramblex  
       2015-12-17 14:26:59 +08:00
    def friend(x):
    ----return list(filter(lambda n: len(n)!=4, x))

    就一行代码的事
    zealot0630
        8
    zealot0630  
       2015-12-17 14:31:09 +08:00
    [v for v in x if len(v) == 4]

    PS: python 的 lambda 实在太难看了
    niqzhao
        9
    niqzhao  
    OP
       2015-12-17 16:14:23 +08:00
    @baichi 这工具简直是坑底照明灯
    niqzhao
        10
    niqzhao  
    OP
       2015-12-17 16:15:57 +08:00
    @bramblex @zealot0630 你们这太 6 了 学习了
    bramblex
        11
    bramblex  
       2015-12-17 18:10:54 +08:00
    @zealot0630 那我这样玩呢?/w\

    friend :: [String] -> [String]
    friend xs = do
    x <- xs
    if length x /= 4
    then return x
    else mempty
    zhangyi2099
        12
    zhangyi2099  
       2015-12-17 18:22:17 +08:00 via iPhone
    @bramblex 这是 Haskell ?
    bramblex
        13
    bramblex  
       2015-12-17 18:26:00 +08:00
    @zhangyi2099 对啊……
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2776 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 12:40 · PVG 20:40 · LAX 04:40 · JFK 07:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.