Understanding this Python code from 2014 New Year challenge

I was just browsing this page here and found this post:

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

      

This is python code and it prints 2014 when executed. Can anyone help a Java developer understand what's going on here?

+3


source to share


6 answers


A few things to understand:



  • The lines are repeated by default, so you can just loop over each element in the line:

    for c in 'Hello there':
        print c
    
          

  • ord

    is a built-in function that returns the actual numeric code point for a character.

  • Expression ord(c) for c in 'Happy new year to you!'

    is a generator expression. The result of this returns the generator function back, which retrieves the results of the complete generator expression on subsequent calls __next__()

    . This happens both under the covers for us and is done lazily; if the element is __next__()

    not called, you don't generate the next value. This is useful if the expression you want to generate contains many values.

    This is actually the gist of the code snippet; it expresses what would need to be written more awkwardly in Java in a shorter way.

  • sum

    takes a list as an argument and returns the total numeric value of its contents.
+5


source


int s = 0;

for (char c: "Happy new year to you!".toCharArray())
  s += (int) c;

System.out.println(s);

      



+4


source


ord()

converts a character to its ASCII value. sum()

adds a set of objects for which an add operation is defined, mathematical scalar's complement in this case.

The expression internally sum()

is a generator expression, a type of iterative operator that has no pure equivalent in Java, but is similar to LINQ in .NET. Basically, it is a loop built into each loop, spanning each character in the string β€œHappy New Year!”, Calculating the ASCII value of the character using ord

and summing those numeric values.

+1


source


1) The ord built-in function returns an integer char value.

>>> 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) the for loop iterates on each char string '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!')

- generator expression in python.

>>> result = (ord(c) for c in 'Happy new year to you!')
>>> result.next()
72
>>> result.next()
97

      

4) the sum built-in function returns the total integer value for each 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.

      

So, the result of combining all these expressions is:

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

      


Another possible solution could be:

>>> sum(map(lambda c:ord(c), 'Happy new year to you!'))
2014

      

+1


source


print

is a statement (in Python 2.x) that will print an expression above it.

(Note that in Python 3.x, a function print()

is a function that outputs its arguments.)

An expression is a call to a built-in function sum()

. Whatever adds up, the result is 2014, so it print

prints 2014

.

sum()

a special construct called "generator expression" is passed. This is similar to list comprehension, but slightly more efficient. [1] Basic generator expression format:

expression for a variable in iterable

Here's a variable c

. An iterable string, 'Happy new year to you!'

Expression is a built-in function call ord()

that returns an integer representing the character being passed; for example ord('A')

returns 65

.

So this sums the ordinal values ​​of all characters in the string; the amount is 2014 and is printed.

[1] Understanding a list creates a list of values. The generator expression didn't build anything, but can be called repeatedly to return one value at a time. Functions in Python that take iterations can take a generator expression and get values ​​from it.

You can write this with a generator expression to build a list and then sum the list. But if you did, the list would be built, looked at right away, and then garbage collected. Why waste the effort of allocating and destroying a list object when all you need is a sum of values? Thus, the generator expression.

0


source


The expression of the shape found in this piece of code and surrounded by "naked" ( )

is called the concept of a generator. It creates a specific type of iteration known as a generator in Python.

There are also other types of concepts. An expression surrounded by bared parentheses would be a list. Example:

[char for char in "string"] 

      

This will create a list:

['s','t','r','i','n','g']

      

And the "bare" curly braces (aka assembly) create a set:

{char for char in "string"} 

      

This does the set:

{'s','t','r','i','n','g'}

      

(There is also vocabulary comprehension.)

As I said at the beginning, using only parentheses around this kind of form expression something for something in something_else

creates a special type of iterator called a generator in Python (not a list or set like the examples above).

However, in Python, many other things are iterable, including strings. Inside the generator, each character is extracted at the end of a line, one by one, one by one, s

, t

, ..., etc. The resulting symbol is the object being referenced char

for this iteration.

The part ord(char)

applies the function ord

to each char

in turn when the string is repeated. The function ord

simply finds the unicode number for a specific character that has been extracted from the string. This unicode value is the result of the common generator for the current iteration.

To get the value of the generator, you need to somehow go through it, for example, using next()

or operator for

... in

. But usually you can also use a generator as an argument for any function that receives an argument iterable. In this case sum()

(which is obviously meant to add a sequence of sequential arguments together) applies to all generator results. Each generator result obtained is a member of the series.

So the overall effect of the code is to concatenate all the unicode character values ​​of the strings. The overall result for 2014 just seems like a coincidence. Nothing mysterious or magical happens there.

-1


source







All Articles