我怎样才能写更多" pythonic"编码时如下?

时间:2016-11-21 21:21:44

标签: python

res = sum((i+j)%k == 0 for x, i in enumerate(a) for j in a[x+1:])

其中a是数组。

我无法理解这段代码在做什么.. i in enumerate(a) for j in a[x+1:]基本上是一行中的for循环以节省空间?

另外我怎么写这样的代码?我正在努力学习python。

3 个答案:

答案 0 :(得分:6)

这是对sum函数调用内的生成器表达式。 sum只是添加内容,所以让我们看一下生成器表达式:

(i+j)%k == 0 for x, i in enumerate(a) for j in a[x+1:]

(i+j)%k == 0部分是布尔表达式。如果i+j0潜水时剩余k,则为真,否则为假。作为一个巧妙的小技巧,True值在python中的数值为1False的数值为0。所以这基本上只算数。

for x, i in enumerate(a) for j in a[x+1:]

这实际上是一个嵌套的for循环。

for x, i in enumerate(a):
    for j in a[x+1:]:

enumerate是一个函数,可以从迭代与其索引配对中生成项目,因此[a, b, c]变为[(0, a), (1, b), (2, c)]

将它们粘在一起,此代码计算列表中元素对的数量,使其总和可被k整除

答案 1 :(得分:4)

你可以"放松"代码如下:

counter=0   # emulates `sum`
for x, i in enumerate(a):
    for j in a[x+1:]:
       counter += (i+j)%k == 0

所以计算(i+j)k整除的次数,避免计算相同的一半和相同的元素(仅计算上面的矩阵三角形)

当您从另一个可迭代或可迭代迭代中创建列表时,列表/生成器理解更好/更快,更简洁,就像这里:您创建了一个布尔列表(0或1),您{{ 1}}计算sum的出现次数。

但不要滥用它们:proper use of list comprehensions - python

有时一个简单的循环调用n次函数会更好(当需要副作用时)。

如果不明智地使用它们会成为一个理解的噩梦(特别是那些带有副作用的单行)

答案 2 :(得分:2)

这些被称为理解。 True遍历一个可迭代对象并返回一个元组enumerate,其中(a, b)是迭代中的索引,a是该索引处的对象。

这是一段很好的pythonic代码。至于学习如何理解/写这样的东西,练习和阅读python文档将是一个很好的起点。请记住,这只是语法糖,你可以在多行中做同样的事情,它几乎完全相同。