在完成Toby Segaran撰写的精彩的“编程集体智慧”一书时,我在索引作业中遇到了一些我并不完全熟悉的技术。
以此为例:
createkey='_'.join(sorted([str(wi) for wi in wordids]))
或:
normalizedscores = dict([(u,float(l)/maxscore) for (u,l) in linkscores.items()])
索引中的所有嵌套元组让我有点困惑。实际上分配给这些变量的是什么?我假设.join
显然是一个字符串,但后者呢?如果有人能够解释这些循环的机制,我真的很感激。我认为这些是非常常见的技术,但对Python来说是新手,我想要问的是片刻的耻辱。谢谢!
答案 0 :(得分:15)
[str(wi) for wi in wordids]
a = [str(wi) for wi in wordids]
与
相同a = []
for wi in wordids:
a.append(str(wi))
所以
createkey='_'.join(sorted([str(wi) for wi in wordids]))
从wordids
中的每个项目创建一个字符串列表,然后对该列表进行排序,并使用_
作为分隔符将其连接成一个大字符串。
正如agf正确指出的那样,你也可以使用一个生成器表达式,它看起来就像一个列表推导,但带括号而不是括号。如果您以后不需要它,则可以避免构建列表(除了迭代它)。如果你已经有sorted(...)
这样的括号,你可以简单地删除括号。
但是,在这种特殊情况下,您将无法获得性能优势(事实上,它会慢大约10%;我计时),因为sorted()
无论如何都需要构建一个列表,但是看起来好一点:
createkey='_'.join(sorted(str(wi) for wi in wordids))
normalizedscores = dict([(u,float(l)/maxscore) for (u,l) in linkscores.items()])
遍历字典linkscores
的项目,其中每个项目都是键/值对。它会创建一个键/ l/maxscore
元组列表,然后将该列表转换回字典。
但是,自Python 2.7起,您还可以使用 dict comprehensions :
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
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)]")
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
答案 1 :(得分:3)
我们来看第一个:
str(wi) for wi in wordids
获取wordids
中的每个元素并将其转换为字符串。sorted(...)
对它们进行排序(按字典顺序排列)。'_'.join(...)
将已排序的单词ID合并为一个字符串,在条目之间带有下划线。现在是第二个:
normalizedscores = dict([(u,float(1)/maxscore) for (u,l) in linkscores.items()])
linkscores
是一个字典(或类字典对象)。for (u,l) in linkscores.items()
遍历字典中的所有条目,为每个条目分配密钥,并将值分配给u
和l
。(u,float(1)/maxscore)
是一个元组,其第一个元素是u
,第二个元素是1/maxscore
(对我而言,这看起来可能是一个拼写错误:{{1}会更有意义 - 注意小写字母el代替一个。)float(l)/maxscore
从元组列表构造一个字典,其中每个元组的第一个元素作为键,第二个元素作为值。简而言之,它会复制字典,保留密钥并将每个值除以dict(...)
。
答案 2 :(得分:1)
后者相当于:
normalizedscores = {}
for u, l in linkscores.items():
normalizedscores[u] = float(l) / maxscore
答案 3 :(得分:1)
[(u,float(1)/maxscore) for (u,l) in linkscores.items()]
这会通过迭代linkscores.items()
中的元组并为每个元组计算(u, float(l)/maxscore)
来创建列表。
dict([this list])
为dict
中的每个项目创建一个(u, float(l)/maxscore)
,其中包含列表推导结果中的条目 - linkscores
。
另一个从元组列表创建dict的例子:
>>> l = [(1,2), (3,4), (5,6)]
>>> d = dict(l)
>>> d
{1: 2, 3: 4, 5: 6}
答案 4 :(得分:1)
以下是第一个例子
的示例>>> 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循环遍历列表,对列表进行排序,然后将所有已排序的值连接成一个字符串,用'_'分隔值
答案 5 :(得分:1)
在[]
括号内发生的奇怪的业务称为列表理解,它基本上是一种构建列表的简洁方法。 myList = [str(wi) for wi in wordids]
相当于:
myList = []
for wi in wordids:
myList.append(str(wi))
sorted()
然后对该列表进行排序,join()
给出一个字符串,其中列表项由下划线分隔,如下所示:item1_item2_item3_...
。
第二项任务更复杂/更简洁,但这是正在发生的事情:
linkscores
看起来像字典,items()
方法从字典中返回(key, value)
元组的列表。所以for (u,l) in linkscores.items()
循环遍历该列表。 (u, float(l)/maxscore)
的新元组,并将其添加到列表中。因此,此步骤基本上将您的(item, value)
列表更改为(item, normalized value)
元组列表。 dict()
函数将其转换回字典。这样做的总体结果是获取dict中的所有值并将它们标准化。可能有一种更简单/更冗长的方式来做到这一点,但这种方式具有看起来很酷的好处。我不喜欢用列表推导做疯狂的事情,因为它会损害可读性,所以如果你不想自己写这种东西,不要感到心疼!