Python:for索引分配中的循环
在阅读托比·塞加兰(Toby Segaran)的著作《编程集体智慧》(Programming Collective Intelligence)的过程中,我遇到了一些我并不完全熟悉的索引分配技巧 以此为例:Python:for索引分配中的循环,python,dictionary,indexing,variable-assignment,Python,Dictionary,Indexing,Variable Assignment,在阅读托比·塞加兰(Toby Segaran)的著作《编程集体智慧》(Programming Collective Intelligence)的过程中,我遇到了一些我并不完全熟悉的索引分配技巧 以此为例: createkey='_'.join(sorted([str(wi) for wi in wordids])) 或: 索引中的所有嵌套元组让我有点困惑。这些变量实际分配了什么?我显然假设.join一个作为字符串出现,但是后者呢?如果有人能解释这些循环的机制,我会非常感激。我认为这些都是非常常
createkey='_'.join(sorted([str(wi) for wi in wordids]))
或:
索引中的所有嵌套元组让我有点困惑。这些变量实际分配了什么?我显然假设
.join
一个作为字符串出现,但是后者呢?如果有人能解释这些循环的机制,我会非常感激。我认为这些都是非常常见的技术,但作为Python新手,我想问一下是一件很遗憾的事。谢谢 后者相当于:
normalizedscores = {}
for u, l in linkscores.items():
normalizedscores[u] = float(l) / maxscore
myList = []
for wi in wordids:
myList.append(str(wi))
这将通过迭代linkscores.items()
中的元组,并为每个元组计算(u,float(l)/maxscore)
来创建一个列表
dict([this list])
为linkscores
中的每个项目创建一个dict
,其中包含列表理解结果中的条目-(u,float(l)/maxscore)
作为从元组列表创建dict的另一个示例:
>>> l = [(1,2), (3,4), (5,6)]
>>> d = dict(l)
>>> d
{1: 2, 3: 4, 5: 6}
让我们看第一个:
排序(…)
对它们进行排序(按字典顺序)normalizedscores = dict([(u,float(1)/maxscore) for (u,l) in linkscores.items()])
linkscores
是一个字典(或类似字典的对象)迭代字典中的所有条目,为每个条目分配键和值给u
和l
(u,float(1)/maxscore)
是一个元组,其中第一个元素是u
,第二个元素是1/maxscore
(对我来说,这看起来可能是一个打字错误:float(l)/maxscore
更有意义——请注意小写字母el代替一个)dict(…)
从元组列表构造一个字典,其中每个元组的第一个元素作为键,第二个元素作为值maxscore
[str(wi) for wi in wordids]
是一个
a = [str(wi) for wi in wordids]
与
a = []
for wi in wordids:
a.append(str(wi))
所以
从wordids
中的每个项目创建一个字符串列表,然后对该列表进行排序,并使用\uu
作为分隔符将其合并为一个大字符串
正如agf正确指出的,您还可以使用生成器表达式,它看起来就像一个列表,但使用括号而不是括号。如果您以后不需要列表,这可以避免构建列表(迭代列表除外)。如果你已经有了括号,比如在这个例子中,sorted(…)
你可以简单地删除括号
但是,在这种特殊情况下,您不会获得性能优势(事实上,它会慢10%左右;我对它进行了计时),因为sorted()
无论如何都需要构建一个列表,但它看起来更好一些:
createkey='_'.join(sorted(str(wi) for wi in wordids))
遍历字典
linkscores
中的项,其中每个项都是一个键/值对。它创建一个key/l/maxscore
元组列表,然后将该列表转换回字典
但是,自Python 2.7以来,您还可以使用:
normalizedscores = {u:float(l)/maxscore for (u,l) in linkscores.items()}
以下是一些计时数据: Python 3.2.2
>>> import timeit
>>> timeit.timeit(stmt="a = '_'.join(sorted([str(x) for x in n]))", setup="import random; n = [random.randint(0,1000) for i in range(100)]")
61.37724242267409
>>> timeit.timeit(stmt="a = '_'.join(sorted(str(x) for x in n))", setup="import random; n = [random.randint(0,1000) for i in range(100)]")
66.01814811313774
>>> import timeit
>>> timeit.timeit(stmt="a = '_'.join(sorted([str(x) for x in n]))", setup="import random; n = [random.randint(0,1000) for i in range(100)]")
58.01728623923137
>>> timeit.timeit(stmt="a = '_'.join(sorted(str(x) for x in n))", setup="import random; n = [random.randint(0,1000) for i in range(100)]")
60.58927580777687
Python 2.7.2
>>> import timeit
>>> timeit.timeit(stmt="a = '_'.join(sorted([str(x) for x in n]))", setup="import random; n = [random.randint(0,1000) for i in range(100)]")
61.37724242267409
>>> timeit.timeit(stmt="a = '_'.join(sorted(str(x) for x in n))", setup="import random; n = [random.randint(0,1000) for i in range(100)]")
66.01814811313774
>>> import timeit
>>> timeit.timeit(stmt="a = '_'.join(sorted([str(x) for x in n]))", setup="import random; n = [random.randint(0,1000) for i in range(100)]")
58.01728623923137
>>> timeit.timeit(stmt="a = '_'.join(sorted(str(x) for x in n))", setup="import random; n = [random.randint(0,1000) for i in range(100)]")
60.58927580777687
这是第一个……例子的一个例子
>>> wordids = [1,2,4,3,10,7]
>>> createkey='_'.join(sorted([str(wi) for wi in wordids]))
>>> print createkey
1_10_2_3_4_7
它所做的是用for循环遍历列表,对列表进行排序,然后将所有已排序的值合并成一个字符串,用“u”分隔值在
[]
括号内发生的奇怪业务称为列表理解,它基本上是构建列表的一种非常简洁的方法myList=[str(wi)表示wordid中的wi]
相当于:
normalizedscores = {}
for u, l in linkscores.items():
normalizedscores[u] = float(l) / maxscore
myList = []
for wi in wordids:
myList.append(str(wi))
sorted()
然后对该列表进行排序,join()
给出一个字符串,其中列表项用下划线分隔,如下所示:item1\u item2\u item3…
第二个作业更复杂/简洁,但下面是发生的情况:
看起来像一个字典,而linkscores
方法从字典中返回items()
元组的列表。因此linkscores.items()中(u,l)的(键,值)
正在该列表上循环李>
- 对于每个元组,我们创建一个包含
的新元组,并将其添加到列表中。因此,这一步基本上将(u,float(l)/maxscore)
列表更改为(项,值)
元组列表李>(项,规范化值)
函数将其转换回字典dict()
- 对于每个元组,我们创建一个包含
这样做的总体结果是获取dict中的所有值并对其进行规范化。也许有一种更简单/更详细的方法可以做到这一点,但这种方法的好处是看起来很酷。我不喜欢用列表理解来做一些疯狂的事情,因为这会损害可读性,所以如果你自己不想写这种东西,也不要觉得很糟糕 @andronikus没有。Python 2.7。我认为作者在撰写本文时可能使用了较旧版本的Python,因为我从他的博客下载了修订后的示例代码,在那里他使用了您描述的字典理解方法。哦,我真该死:。反对撤回@我已经把我的答案说得更清楚了,谢谢。毕竟,Python2.5和2.6仍然被广泛使用……是的,我想我仍然使用其中的一种。到目前为止,我从未听说过听写理解,这对我没有帮助。很酷+2如果你解释一下列表comp的基本功能(我感觉OP没有意识到,但我可能错了),那么每个人都提到了列表理解。人们没有提到的是那些例子