Python:用于索引赋值的循环

时间:2011-10-14 14:08:53

标签: python dictionary indexing variable-assignment

在完成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来说是新手,我想要问的是片刻的耻辱。谢谢!

6 个答案:

答案 0 :(得分:15)

[str(wi) for wi in wordids]

list comprehension

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)

我们来看第一个:

  1. str(wi) for wi in wordids获取wordids中的每个元素并将其转换为字符串。
  2. sorted(...)对它们进行排序(按字典顺序排列)。
  3. '_'.join(...)将已排序的单词ID合并为一个字符串,在条目之间带有下划线。
  4. 现在是第二个:

    normalizedscores = dict([(u,float(1)/maxscore) for (u,l) in linkscores.items()])
    
    1. linkscores是一个字典(或类字典对象)。
    2. for (u,l) in linkscores.items()遍历字典中的所有条目,为每个条目分配密钥,并将值分配给ul
    3. (u,float(1)/maxscore)是一个元组,其第一个元素是u,第二个元素是1/maxscore(对我而言,这看起来可能是一个拼写错误:{{1}会更有意义 - 注意小写字母el代替一个。)
    4. float(l)/maxscore从元组列表构造一个字典,其中每个元组的第一个元素作为键,第二个元素作为值。
    5. 简而言之,它会复制字典,保留密钥并将每个值除以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中的所有值并将它们标准化。可能有一种更简单/更冗长的方式来做到这一点,但这种方式具有看起来很酷的好处。我不喜欢用列表推导做疯狂的事情,因为它会损害可读性,所以如果你不想自己写这种东西,不要感到心疼!