5

I am quite new to python. Can someone explain this line

exec("print(' '.join(map(lambda x: s[x::{0}], range({0}))))".format(ceil(sqrt(len(s)))))

What does s[x::{0}] and range({0})) mean ?

in below piece of code in detail?

This code is a solution for below hackerrank question : https://www.hackerrank.com/challenges/encryption/problem

#!/bin/python3

import sys
from math import ceil, floor, sqrt


def encryption(s):
    exec("print(' '.join(map(lambda x: s[x::{0}], range({0}))))".format(ceil(sqrt(len(s)))))

if __name__ == "__main__":
    s = input().strip()
    result = encryption(s)
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
pythonaddict
  • 283
  • 3
  • 4
  • 13

4 Answers4

5

This is a simplified version of your code, which you should be able to follow:

from math import ceil, sqrt

s = 'hello'

y = ceil(sqrt(len(s)))
# 3

res = ' '.join(map(lambda x: s[x::y], range(y)))
# 'hl eo l'

Essential points

  • y is the rounded-up square root of the length of s, in this case sqrt(5) is rounded up to 3.
  • lambda is an anonymous function which maps each value in range(y), i.e. 0, 1, 2 is mapped to s[x::y], i.e. return every yth element of sequence beginning from index x. See also Understanding Python's slice notation. x is arbitrary notation for a member of range(y).
  • Join all resulting values with a space to form a single string.
  • In your original code {0} and str.format are used to incorporate y in your string in one line. In this case, I consider it convoluted and bad practice.
jpp
  • 159,742
  • 34
  • 281
  • 339
  • what does x stand for here? Each value in range(y), i.e. 0, 1, 2 is mapped to s[x::y], i.e. return every yth element of sequence beginning from index x. how lambda function mapping takes place in this casE? – pythonaddict Mar 19 '18 at 11:48
  • Sorry I understood now, it is like for each element of the list, iterate from current element (x) to range(y). so first iteration will produce hel, 2nd will produce lo. when we do " ".join(hel,lo), it will produce "hl eo l" – pythonaddict Mar 19 '18 at 11:54
1

This line is using the format() function on a string. Thus, the {0} will be replaced by the first element in the format function which is ceil(sqrt(len(s))))

Hugo
  • 1,106
  • 15
  • 25
1

When using the str.format() method (see here), the brackets and characters in them will be replaced with the objects passed in the method. The "0" indicates replacement with the first character passed in the method.

Jonathan S.
  • 26
  • 1
  • 5
0

From the documetnation you can see what format() does.

In your example:

exec("print(' '.join(map(lambda x: s[x::{0}], range({0}))))".format(ceil(sqrt(len(s)))))

You are inserting the result of ceil(sqrt(len(s))) in two places, namely:

lambda x: s[x::ceil(sqrt(len(s)))]

and

range(ceil(sqrt(len(s))))

Now, exec could be avoided here with simple variable:

def encryption(s):
    var = ceil(sqrt(len(s)))
    print(' '.join(map(lambda x: s[x::var], range(var))))
zipa
  • 27,316
  • 6
  • 40
  • 58