Malav
Malav

Reputation: 13

Can anybody please explain me the meaning of this statement written in Python?

req = urllib2.Request(
    "".join(
        url[i].replace(' ', '%20') if i > url.find('?') else url[i]
        for i in xrange(len(url))
    ),
    data,
    _headers
)

I am new to Python. Please simplify this code for me.

Upvotes: 1

Views: 119

Answers (2)

James Sapam
James Sapam

Reputation: 16940

Here is m trying to rewrite using for loop to make you better understand:

  ls = list()
  url = 'https://www.facebook.com/?ref=here is me'
  for i in range(len(url)):
      # all the element after '?'
      if i > url.find('?'):
          ls.append(url[i].replace(' ', '%20'))
      else:
          ls.append(url[i])

  nurl = ''.join(ls)
  # nurl = https://www.facebook.com/?ref=here%20is%20me
  req = urllib2.Request(nurl, data, _headers)

Upvotes: 0

Chris Morgan
Chris Morgan

Reputation: 90832

[f(url[i]) for i in xrange(len(url))] is an antipattern in Python. (xrange(len(x)) is something you should pretty much never write.) It's basically doing something to each character of the URL (assuming url to be a string). You should instead use something more like [f(char) for char in url], or if an index is necessary, use enumerate.

"".join(…) means that for an iterable of characters they will be joined with nothing ("") between them.

Thus,

url = ''.join(
        char.replace(' ', '%20') if i > url.find('?') else char
        for i, char in enumerate(url)
    )

That part is a dodgy way of replacing spaces () with %20 in the query string only (after the ? symbol).

Breaking it down, we have a generator expression, (a for b in c), and as the expression of the generator, char.replace(' ', '%20') if i > url.find('?') else char, which means "if i is greater than url.find('?'), then use char.replace(' ', '%20'), otherwise use char.

As a simple example of what it's doing, if url was foo bar?baz quux, we would end up with foo bar?baz%20quux—the space after the ? is replaced with %20.

Retaining the same functionality, this could also be written by using str.partition and str.replace more succinctly and efficiently:

>>> url = 'foo bar?baz quux'
>>> lhs, pivot, rhs = url.partition('?')
>>> lhs + pivot + rhs.replace(' ', '%20')
'foo bar?baz%20quux'

What's left is then straightforward and requires no explanation as the docs explain it:

req = urllib2.Request(url, data, _headers)

Upvotes: 1

Related Questions