简体   繁体   English

如何在编码时编写更多“pythonic”?

[英]How can I write more “pythonic” when coding like the following?

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

where a is an array. 其中a是一个数组。

I cannot understand what this code is doing..is the i in enumerate(a) for j in a[x+1:] basically a for loop inside that line to save space? 我无法理解这段代码在做什么.. i in enumerate(a) for j in a[x+1:]基本上是为了节省空间而在该行内的for循环?

Also how can I write code like this? 另外我怎么写这样的代码? I am trying to learn python. 我正在努力学习python。

This is a generator expression inside a call to the sum function. 这是对sum函数调用内的生成器表达式。 sum just adds things up, so let's look at the generator expression: sum只是添加了东西,所以让我们看一下生成器表达式:

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

The (i+j)%k == 0 part is a boolean expression. (i+j)%k == 0部分是布尔表达式。 It's either true if i+j has a remainder of 0 when dived by k or false otherwise. 如果i+j在被k潜水时具有0的余数,则为真,否则为假。 As a neat little trick, the True value has a numeric value of 1 in python, and False has a numeric value of 0 . 作为一个巧妙的小技巧, True值在python中的数值为1 ,而False的数值为0 So this is basically just counting. 所以这基本上只算数。

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

This is essentially a nested for loop. 这本质上是一个嵌套的for循环。

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

enumerate is a function that yields items from an iterable paired with their index, so [a, b, c] becomes [(0, a), (1, b), (2, c)] enumerate是一个从迭代与其索引配对产生项的函数,因此[a, b, c]变为[(0, a), (1, b), (2, c)]

Stick it all together, and this code calculates the number of pairs of elements in a list such that their sum is divisible by k 将它们全部粘在一起,并且此代码计算列表中元素对的数量,使得它们的总和可被k整除

you can "unwind" the code as follows: 您可以按如下方式“展开”代码:

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

so it counts the occurrences of (i+j) being divisible by k , avoiding to count the same half and identical elements (only counts the upper matrix triangle) 所以计算(i+j)出现可以被k整除,避免计算相同的一半和相同的元素(只计算上面的矩阵三角形)

List/generator comprehensions are better/faster and more concise when you're creating a list out of another iterable or iterable of iterable, like here: you created a list of booleans (0 or 1) that you sum to count the occurrences of True . 当您从另一个可迭代或可迭代迭代中创建列表时,列表/生成器理解更好/更快,更简洁,如下所示:您创建了一个布尔值列表(0或1),您可以将它们sum加以计算True的出现次数。

But don't abuse of them: proper use of list comprehensions - python 但是不要滥用它们: 正确使用列表推导 - python

sometimes a plain loop to call n times a function is better (also when a side-effect is required). 有时一个简单的循环调用n次函数会更好(当需要副作用时)。

When used unwisely they can become a nightmare to understand (specially the one-liners with side-effects in them) 如果使用不明智,他们可能会成为一个理解的噩梦(特别是其中有副作用的单行)

These are called comprehensions. 这些被称为理解。 enumerate iterates through an iterable object and returns a tuple (a, b) where a is the index in the iterable, and b is object at that index. enumerate遍历可迭代对象并返回元组(a, b) ,其中a是可迭代中的索引, b是该索引处的对象。

This is a nice piece of pythonic code. 这是一个很好的pythonic代码。 As for learning how to understand/write stuff like this, practice, and reading python documentation would be a great place to start. 至于学习如何理解/写这样的东西,练习和阅读python文档将是一个很好的起点。 Remember, this is simply just syntactic sugar, you can do the same thing in multiple lines and it will work almost exactly the same. 请记住,这只是语法糖,你可以在多行中做同样的事情,它几乎完全相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM