Python:用于索引赋值的循环

Dea*_*ado 4 python indexing dictionary variable-assignment

在完成Toby Segaran撰写的精彩的"编程集体智慧"一书时,我遇到了一些我并不完全熟悉的索引分配技巧.

以此为例:

createkey='_'.join(sorted([str(wi) for wi in wordids]))
Run Code Online (Sandbox Code Playgroud)

要么:

normalizedscores = dict([(u,float(l)/maxscore) for (u,l) in linkscores.items()])
Run Code Online (Sandbox Code Playgroud)

索引中的所有嵌套元组让我有点困惑.实际上分配给这些变量的是什么?我假设显然是.join一个字符串,但后者怎么样?如果有人能够解释这些循环的机制,我真的很感激.我认为这些是非常常见的技术,但对Python来说是新手,我想要问的是片刻的耻辱.谢谢!

Tim*_*ker 15

[str(wi) for wi in wordids]
Run Code Online (Sandbox Code Playgroud)

列表理解.

a = [str(wi) for wi in wordids]
Run Code Online (Sandbox Code Playgroud)

是相同的

a = []
for wi in wordids:
    a.append(str(wi))
Run Code Online (Sandbox Code Playgroud)

所以

createkey='_'.join(sorted([str(wi) for wi in wordids]))
Run Code Online (Sandbox Code Playgroud)

从每个项目中创建一个字符串列表wordids,然后对该列表进行排序,并使用它_作为分隔符将其连接成一个大字符串.

正如agf正确指出的那样,你也可以使用一个生成器表达式,它看起来就像一个列表推导,但带括号而不是括号.如果您以后不需要它,则可以避免构建列表(除了迭代它).如果你已经有了括号,就像在这种情况下sorted(...)你可以简单地删除括号.

但是,在这种特殊情况下,您将无法获得性能优势(事实上,它会慢大约10%;我计时)因为sorted()无论如何都需要构建一个列表,但它看起来更好一些:

createkey='_'.join(sorted(str(wi) for wi in wordids))
Run Code Online (Sandbox Code Playgroud)
normalizedscores = dict([(u,float(l)/maxscore) for (u,l) in linkscores.items()])
Run Code Online (Sandbox Code Playgroud)

遍历字典中的项目linkscores,其中每个项目是键/值对.它创建一个键/ l/maxscore元组列表,然后将该列表转换回字典.

但是,从Python 2.7开始,你也可以使用dict理解:

normalizedscores = {u:float(l)/maxscore for (u,l) in linkscores.items()}
Run Code Online (Sandbox Code Playgroud)

这是一些时间数据:

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)