从2014年的新年挑战中了解这段Python代码

时间:2015-01-01 05:21:45

标签: python

我刚刚浏览了这个页面here并找到了这个条目:

print sum(ord(c) for c in 'Happy new year to you!')

它是python代码,并在执行时打印2014.有人可以帮助Java开发人员准确理解这里发生了什么吗?

6 个答案:

答案 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中,许多其他东西是可迭代的,包括字符串。在生成器内部,每个字符都会在字符串迭代时被检索,一次调用一个字符,依次调用st,...等等。检索到的字符就是char为该迭代引用的对象。

ord(char)部分在迭代字符串时依次将ord函数应用于每个charord函数只查找从字符串中检索到的特定字符的unicode编号。然后,该unicode值是当前迭代的整个生成器的结果。

要从生成器中获取值,您必须以某种方式迭代它 - 例如使用next()for ... in语句。但通常您也可以将生成器作为参数应用于任何接收参数的iterable的函数。在这种情况下,sum()(显然意味着将一系列连续的参数加在一起)被应用于生成器的所有结果。发电机的每个产生的结果都是该系列的成员。

因此代码的整体效果是将字符串字符的所有unicode值加在一起。 2014年的整体结果似乎是巧合。那里没有任何神秘或神奇的东西。