关于一段Python的迭代问题请教

56 views
Skip to first unread message

ihipop

unread,
Nov 1, 2010, 2:37:12 AM11/1/10
to python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表)

小弟我上次吃饱了饭逛大神们的blog,发现bones的某篇日志(http://luy.li/2010/09/17/
python_traversal_dict/)下面这么一段小小的争论。

python 是推荐使用迭代器的,也就是 for k in adict 形式。其次,在遍历中删除容器中的元素,在 C++ STL 和
Python 等库中,都是不推荐的,因为这种情况往往说明了你的设计方案有问题,所有都有特殊要求,对应到 python 中,就是要使用
adict.key() 做一个拷贝。最后,所有的 Python 容器都不承诺线程安全,你要多线程做这件事,本身就必须得加锁,这也说明了业务代码
设计有问题的
但由“遍历中删除特定元素”这种特例,得出“遍历dict的时候,养成使用 for k in d.keys() 的习惯”,我觉得有必要纠正一下。在
普通的遍历中,应该使用 for k in adict。
另外,对于“遍历中删除元素”这种需求,pythonic 的做法是 adict = {k, v for adict.iteritems()
if v != 0} 或 alist = [i for i in alist if i != 0]

他所说的pythonic 的做法到底是伪代码还是Python的语法???
http://ihipop.info/2010/10/1777.html
我从没见过这样的写法~~~
求教!

Leo Jay

unread,
Nov 1, 2010, 2:44:55 AM11/1/10
to pyth...@googlegroups.com
2010/11/1 ihipop <ihi...@gmail.com>

那就试试看呗:
>>> alist = [1,2,0,3,0,4,5]


>>> alist = [i for i in alist if i != 0]

>>> alist
[1, 2, 3, 4, 5]


--
Best Regards,
Leo Jay

KingLiang Gu

unread,
Nov 1, 2010, 2:49:24 AM11/1/10
to pyth...@googlegroups.com
>>> d = {'a':1, 'b':0, 'c':1, 'd':0}

>>> d = {k,v for d.iteritems() if v != 0}
  File "<stdin>", line 1
    d = {k,v for d.iteritems() if v != 0}

我测试了啊,报错!!!

--
来自: python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表)
发言: pyth...@googlegroups.com
退订: python-cn+...@googlegroups.com (向此发空信即退!)
详情: http://groups-beta.google.com/group/python-cn
严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp

ihipop

unread,
Nov 1, 2010, 2:50:53 AM11/1/10
to python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表)
为什么我的报错?

>>> d = {'a':1, 'b':0, 'c':1, 'd':0}
>>> d = {k,v for d.iteritems() if v != 0}
File "<stdin>", line 1
d = {k,v for d.iteritems() if v != 0}

limodou

unread,
Nov 1, 2010, 2:53:56 AM11/1/10
to pyth...@googlegroups.com
2010/11/1 ihipop <ihi...@gmail.com>:

> 为什么我的报错?
>>>> d = {'a':1, 'b':0, 'c':1, 'd':0}
>>>> d = {k,v for d.iteritems() if v != 0}
> File "<stdin>", line 1
> d = {k,v for d.iteritems() if v != 0}

你这是什么语法?

--
I like python!
UliPad <<The Python Editor>>: http://code.google.com/p/ulipad/
UliWeb <<simple web framework>>: http://uliwebproject.appspot.com
My Blog: http://hi.baidu.com/limodou

KingLiang Gu

unread,
Nov 1, 2010, 2:56:32 AM11/1/10
to pyth...@googlegroups.com
他的原文里面有提到的啊,不过换成了字典就不行

>>> adict={'a':1, 'b':0, 'c':1, 'd':0}
>>> adict = {k, v for adict.iteritems() if v != 0}
  File "<stdin>", line 1
    adict = {k, v for adict.iteritems() if v != 0}
              ^
SyntaxError: invalid syntax

ihipop

unread,
Nov 1, 2010, 2:57:59 AM11/1/10
to python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表)

差别在哪里?
On 11月1日, 上午10时56分, KingLiang Gu <ihi...@gmail.com> wrote:
> 他的原文里面有提到的啊,不过换成了字典就不行
>
> >>> adict={'a':1, 'b':0, 'c':1, 'd':0}
> >>> adict = {k, v for adict.iteritems() if v != 0}
>
> File "<stdin>", line 1
> adict = {k, v for adict.iteritems() if v != 0}
> ^
> SyntaxError: invalid syntax
>
> 在 2010年11月1日 上午10:53,limodou <limo...@gmail.com>写道:
>
> > 2010/11/1 ihipop <ihi...@gmail.com>:
> > > 为什么我的报错?
> > >>>> d = {'a':1, 'b':0, 'c':1, 'd':0}
> > >>>> d = {k,v for d.iteritems() if v != 0}
> > > File "<stdin>", line 1
> > > d = {k,v for d.iteritems() if v != 0}
>
> > 你这是什么语法?
>
> > --
> > I like python!
> > UliPad <<The Python Editor>>:http://code.google.com/p/ulipad/
> > UliWeb <<simple web framework>>:http://uliwebproject.appspot.com
> > My Blog:http://hi.baidu.com/limodou
>
> > --
> > 来自: python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表)
> > 发言: pyth...@googlegroups.com
> > 退订: python-cn+...@googlegroups.com<python-cn%2Bunsu...@googlegroups.com>(向此发空信即退!)

limodou

unread,
Nov 1, 2010, 2:58:23 AM11/1/10
to pyth...@googlegroups.com
2010/11/1 KingLiang Gu <ihi...@gmail.com>:

> 他的原文里面有提到的啊,不过换成了字典就不行
>>>> adict={'a':1, 'b':0, 'c':1, 'd':0}
>>>> adict = {k, v for adict.iteritems() if v != 0}
> File "<stdin>", line 1
> adict = {k, v for adict.iteritems() if v != 0}
> ^
> SyntaxError: invalid syntax

因为没这样的语法。既不是list综合语法,也不是generator语法。

Leo Jay

unread,
Nov 1, 2010, 2:59:18 AM11/1/10
to pyth...@googlegroups.com
2010/11/1 ihipop <ihi...@gmail.com>:

> 为什么我的报错?
>>>> d = {'a':1, 'b':0, 'c':1, 'd':0}
>>>> d = {k,v for d.iteritems() if v != 0}
>  File "<stdin>", line 1
>    d = {k,v for d.iteritems() if v != 0}
>

这个要这样写:
>>> d = dict((k,v) for k,v in d.iteritems() if v != 0)
>>> d
{'a': 1, 'c': 1}

ihipop

unread,
Nov 1, 2010, 3:05:52 AM11/1/10
to python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表)
果然够Pythonic。。
谢谢。不过我发现
d = {(k,v) for k,v in d.iteritems() if v != 0}
这样居然不行啊

闲云无心

unread,
Nov 1, 2010, 3:07:28 AM11/1/10
to pyth...@googlegroups.com
--
来自: python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表)
发言: pyth...@googlegroups.com
退订: python-cn+...@googlegroups.com (向此发空信即退!)


版本要求>=py2.7

Yin Desheng

unread,
Nov 1, 2010, 3:08:58 AM11/1/10
to pyth...@googlegroups.com
{k:v for k,v in d.iteritems() if v!=5}


在 2010年11月1日 上午11:05,ihipop <ihi...@gmail.com>写道:

ihipop

unread,
Nov 1, 2010, 3:10:26 AM11/1/10
to python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表)
2.7可以用

d = {(k,v) for k,v in d.iteritems() if v != 0}
这样的形式?

Python的版本兼容太蛋疼了。。。。

On 11月1日, 上午11时07分, 闲云无心 <xianyunwu...@gmail.com> wrote:
> 在 2010年11月1日 上午11:05,ihipop <ihi...@gmail.com>写道:
>
>
>
> > 果然够Pythonic。。
> > 谢谢。不过我发现
> > d = {(k,v) for k,v in d.iteritems() if v != 0}
> > 这样居然不行啊
>
> > On 11月1日, 上午10时59分, Leo Jay <python.leo...@gmail.com> wrote:
> > > 2010/11/1 ihipop <ihi...@gmail.com>:
>
> > > > 为什么我的报错?
> > > >>>> d = {'a':1, 'b':0, 'c':1, 'd':0}
> > > >>>> d = {k,v for d.iteritems() if v != 0}
> > > > File "<stdin>", line 1
> > > > d = {k,v for d.iteritems() if v != 0}
>
> > > 这个要这样写:
>
> > > >>> d = dict((k,v) for k,v in d.iteritems() if v != 0)
> > > >>> d
> > > {'a': 1, 'c': 1}
>
> > > --
> > > Best Regards,
> > > Leo Jay
>
> > --
> > 来自: python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表)
> > 发言: pyth...@googlegroups.com

> > 退订: python-cn+...@googlegroups.com<python-cn%2Bunsu...@googlegroups.com>(向此发空信即退!)

老光

unread,
Nov 1, 2010, 3:04:08 AM11/1/10
to pyth...@googlegroups.com
字典的定义形式错误,for..in表达式错误.
 
d = dict([(k,v) for k,v in d.iteritems() if v!=0])
 
d
{'a':1,'c':1'}

闲云无心

unread,
Nov 1, 2010, 3:13:41 AM11/1/10
to pyth...@googlegroups.com


在 2010年11月1日 上午11:13,闲云无心 <xianyu...@gmail.com>写道:


退订: python-cn+...@googlegroups.com (向此发空信即退!)



刚没注意,你给的那段写错了,一半是<2.7的用户,一半是>=2.7的用户....

>= 2.7    {k:v for k,v in d.iteritems() if v !=0 }
<2.7     dict([ (k,v) for k,v in d.iteritems() if v !=0 ])


用户->用法,今天昏头了......

闲云无心

unread,
Nov 1, 2010, 3:13:13 AM11/1/10
to pyth...@googlegroups.com
在 2010年11月1日 上午11:10,ihipop <ihi...@gmail.com>写道:

严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp



刚没注意,你给的那段写错了,一半是<2.7的用户,一半是>=2.7的用户....

>= 2.7    {k:v for k,v in d.iteritems() if v !=0 }
<2.7     dict([ (k,v) for k,v in d.iteritems() if v !=0 ])

ihipop

unread,
Nov 1, 2010, 3:15:31 AM11/1/10
to python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表)
谢谢老大们指教。。

On 11月1日, 上午11时13分, 闲云无心 <xianyunwu...@gmail.com> wrote:

> >> <python-cn%2Bunsu...@googlegroups.com<python-cn%252Buns...@googlegroups.com>


> >> >(向此发空信即退!)
> >> > > 详情:http://groups-beta.google.com/group/python-cn
> >> > > 严正: 理解列表! 智慧提问!http://wiki.woodpecker.org.cn/moin/AskForHelp
>
> >> > 版本要求>=py2.7
>
> >> --
> >> 来自: python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表)
> >> 发言: pyth...@googlegroups.com
> >> 退订: python-cn+...@googlegroups.com<python-cn%2Bunsu...@googlegroups.com>(向此发空信即退!)
> >> 详情:http://groups-beta.google.com/group/python-cn
> >> 严正: 理解列表! 智慧提问!http://wiki.woodpecker.org.cn/moin/AskForHelp
>

Leo Jay

unread,
Nov 1, 2010, 3:27:08 AM11/1/10
to pyth...@googlegroups.com
2010/11/1 闲云无心 <xianyu...@gmail.com>:

>
> 刚没注意,你给的那段写错了,一半是<2.7的用户,一半是>=2.7的用户....
>
>>= 2.7    {k:v for k,v in d.iteritems() if v !=0 }
> <2.7     dict([ (k,v) for k,v in d.iteritems() if v !=0 ])
>

中括号可以去掉。

ihipop

unread,
Nov 1, 2010, 3:29:54 AM11/1/10
to python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表)
确实,我也发现了。

On 11月1日, 上午11时27分, Leo Jay <python.leo...@gmail.com> wrote:
> 2010/11/1 闲云无心 <xianyunwu...@gmail.com>:

fengjian

unread,
Nov 1, 2010, 7:36:55 AM11/1/10
to pyth...@googlegroups.com
st=[1,2,3,4,5]
map((lambda x:x==2 and st.remove(x)), st)

纯粹无聊^_^

> --
> 来自: python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表)
> 发言: pyth...@googlegroups.com

> 退订: python-cn+...@googlegroups.com (向此发空信即退!)

老光

unread,
Nov 1, 2010, 8:21:57 AM11/1/10
to pyth...@googlegroups.com
为什么不用filter?

st=[1,2,3,4,5]

map((lambda x:x==2 and st.remove(x)), st)
这个得到:
[False, None, False, False]
filter(lambda x:x!=2, st)
[1,3,4,5]

----- Original Message -----
From: "fengjian" <fengjia...@gmail.com>
To: <pyth...@googlegroups.com>

fengjian

unread,
Nov 1, 2010, 8:28:17 AM11/1/10
to pyth...@googlegroups.com
On Mon, Nov 01, 2010 at 04:21:57PM +0800, 老光 wrote:
> 为什么不用filter?
>
> st=[1,2,3,4,5]
>
> map((lambda x:x==2 and st.remove(x)), st)
> 这个得到:
> [False, None, False, False]
> filter(lambda x:x!=2, st)
> [1,3,4,5]

filter要赋值一次。

实际上st已经被修改了。

In [11]: st=[1,2,3,4]

In [12]: map((lambda x:x==2 and st.remove(x)), st)
Out[12]: [False, None, False]

In [13]: st
Out[13]: [1, 3, 4]

当然,只是好玩。^_^

Shell Xu

unread,
Nov 1, 2010, 9:00:57 AM11/1/10
to pyth...@googlegroups.com
效率上说,remove的效率并不一定比filter高,因为list是vector的内存管理模式,remove的O介于O(1)-O(n)之间,而且会间歇触发内存回收动作。
如果大量对象需要移除,可以使用filter。如果只是一两个(概率上说小于两个才合算),可以去remove。
无能者无所求,饱食而遨游,泛若不系之舟

bones7456

unread,
Nov 1, 2010, 11:29:36 AM11/1/10
to python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表)
呵呵,他那个语法就当是伪代码吧~
PS:Akismet把你的评论当spam了。。。

KingLiang Gu

unread,
Nov 1, 2010, 11:41:45 AM11/1/10
to pyth...@googlegroups.com
居然惊动了骨头兄弟。。。。。

Crane Jin

unread,
Nov 2, 2010, 9:45:45 AM11/2/10
to pyth...@googlegroups.com
这样写亦可:

d = {(k,v) for (k,v) in d.items() if v!=0}

2010/11/1 Leo Jay <python...@gmail.com>
Best Regards,
Leo Jay

Leo Jay

unread,
Nov 2, 2010, 9:56:19 AM11/2/10
to pyth...@googlegroups.com
2010/11/2 Crane Jin <crane...@gmail.com>:

> 这样写亦可:
> d = {(k,v) for (k,v) in d.items() if v!=0}
>

在2.6里报错:


>>> d = {(k,v) for (k,v) in d.items() if v!=0}

File "<stdin>", line 1

d = {(k,v) for (k,v) in d.items() if v!=0}

^
SyntaxError: invalid syntax

Yin Desheng

unread,
Nov 2, 2010, 1:18:45 PM11/2/10
to pyth...@googlegroups.com
2.6没Dictionary comprehensions

Best Regards,
Leo Jay

Crane Jin

unread,
Nov 3, 2010, 2:41:15 AM11/3/10
to pyth...@googlegroups.com
哦,那可能是3.0新加的feature 我机器上是3.1.2

2010/11/2 Yin Desheng <dsyin...@gmail.com>
330.gif
Reply all
Reply to author
Forward
0 new messages