我刚刚浏览了这个页面here并找到了这个条目:
print sum(ord(c) for c in 'Happy new year to you!')
它是python代码,并在执行时打印2014.有人可以帮助Java开发人员准确理解这里发生了什么吗?
答案 0 :(得分:5)
要理解的一些事情:
默认情况下,字符串是可迭代的,因此可以简单地遍历字符串中的每个元素:
for c in 'Hello there':
print c
ord
是一个内置函数,它返回一个字符的实际数字代码点。
表达式ord(c) for c in 'Happy new year to you!'
是generator expression。结果返回一个生成器函数,它在后续调用__next__()
时检索总生成器表达式的结果。这既发生在我们的掩护下,又以懒惰的方式完成;如果__next__()
件未被调用,则您不会生成下一个值。如果要生成的表达式包含 lot 值,则此选项非常有用。
这实际上是代码片段的关键;它表达的东西必须以更简洁的方式在Java中更加笨拙地写出来。
sum
将列表作为参数并返回其内容的总数值。答案 1 :(得分:4)
int s = 0;
for (char c: "Happy new year to you!".toCharArray())
s += (int) c;
System.out.println(s);
答案 2 :(得分:1)
ord()
将字符转换为ASCII值。 sum()
将为其定义了加法运算的对象集合,在这种情况下添加了数学标量。
sum()
中的表达式是一个生成器表达式,一种可迭代的语句,在Java中没有一个干净的等价物,但类似于.NET中的LINQ。本质上,它是一个内联for-each循环,循环遍历字符串中的每个字符"祝你新年快乐!",用ord
计算字符的ASCII值,并将它们相加数值。
答案 3 :(得分:1)
1)内置函数ord返回char的整数值。
>>> help(ord)
Help on built-in function ord in module __builtin__:
ord(...)
ord(c) -> integer
Return the integer ordinal of a one-character string.
2) for 循环对字符串'Happy new year to you!'
的每个字符进行迭代
>>> for c in 'Happy new year to you':
... print ord(c)
...
72
97
112
112
...
3)(ord(c) for c in 'Happy new year to you!')
是python中的 generator 表达式。
>>> result = (ord(c) for c in 'Happy new year to you!')
>>> result.next()
72
>>> result.next()
97
4)sum内置函数返回每个char的整数值的总和:
>>> help(sum)
Help on built-in function sum in module __builtin__:
sum(...)
sum(sequence[, start]) -> value
Returns the sum of a sequence of numbers (NOT strings) plus the value
of parameter 'start' (which defaults to 0). When the sequence is
empty, returns start.
所以结合所有这些表达的结果是:
>>> sum(ord(c) for c in 'Happy new year to you!')
2014
另一种可能的解决方案可能是:
>>> sum(map(lambda c:ord(c), 'Happy new year to you!'))
2014
答案 4 :(得分:0)
print
是一个声明(在Python 2.x中),它将打印其后面的表达式。
(请注意,在Python 3.x中,print()
是一个打印其参数的函数。)
表达式是对内置函数sum()
的调用。无论总结是什么,结果都是2014年,因此print
打印2014
。
sum()
正在传递一个称为“生成器表达式”的特殊构造。这类似于“列表理解”,但效率更高。[1]生成器表达式的基本格式为:
此处,变量为c
。 iterable 是一个字符串,'Happy new year to you!'
表达式是对内置函数ord()
的调用,它返回一个表示字符的整数通过;例如,ord('A')
会返回65
。
因此,它将字符串中所有字符的序数值相加;总和是2014年,并打印出来。
[1]列表理解构建了一个值列表。生成器表达式不会构建任何内容,但可以重复调用以一次生成一个值。 Python中接受迭代的函数能够接受生成器表达式并从中获取值。
您可以使用生成器表达式编写此代码来构建列表,然后对列表求和。但是,如果你这样做,列表将被构建,查看一次,然后垃圾收集。当你想要的只是对值进行求和时,为什么要浪费精力来分配和销毁列表对象?因此,生成器表达式。
答案 5 :(得分:-1)
在此代码段中找到并由“naked”( )
包围的表单的表达式称为生成器理解。它产生一种特定类型的迭代,称为Python中的生成器。
还有其他类型的理解。用括号括起来的表达式将是列表推导。示例:
[char for char in "string"]
这将产生一个列表:
['s','t','r','i','n','g']
“裸”括号(又名集合理解)产生一组:
{char for char in "string"}
这使得集合:
{'s','t','r','i','n','g'}
(还有字典理解。)
正如我在第一篇中所说的那样,只使用括号something for something in something_else
这种形式的括号产生一种特殊的迭代器,在Python中称为生成器(而不是列表或集合,如上所述)例子)。
然而,在Python中,许多其他东西是可迭代的,包括字符串。在生成器内部,每个字符都会在字符串迭代时被检索,一次调用一个字符,依次调用s
,t
,...等等。检索到的字符就是char
为该迭代引用的对象。
ord(char)
部分在迭代字符串时依次将ord
函数应用于每个char
。 ord
函数只查找从字符串中检索到的特定字符的unicode编号。然后,该unicode值是当前迭代的整个生成器的结果。
要从生成器中获取值,您必须以某种方式迭代它 - 例如使用next()
或for
... in
语句。但通常您也可以将生成器作为参数应用于任何接收参数的iterable的函数。在这种情况下,sum()
(显然意味着将一系列连续的参数加在一起)被应用于生成器的所有结果。发电机的每个产生的结果都是该系列的成员。
因此代码的整体效果是将字符串字符的所有unicode值加在一起。 2014年的整体结果似乎是巧合。那里没有任何神秘或神奇的东西。