4

I have a line of python code I'm trying to de-cipher from a function that parses a line from a file that's being read. I've annotated the lines that I do understand with comments

#split a line that is read from the file by spaces.
line = annotation_line.split()

#Open the file, represented by the first arg in the lines
#Lines are structured as below:
#/path/to/Image.png x1,y1,x2,y2,classNo x1,y1,x2,y2,classNo [etc]
#|Image file path  | Box for object 1  | Box for object 2  | Box for object n.
image = Image.open(line[0])

# grab the width and height of the image
iw, ih = image.size

#in this case 604 by 604.
h, w = input_shape

#line in question.
box = np.array([np.array(list(map(int,box.split(',')))) for box in line[1:]])

Here's what I think that the line does:
So first I break this up into individual functions.

The first parameter I break it up into this parameter:

stage1 = map(int,box.split(','))   

Now int isn't a local or global variable, but it is used as a function, and I cannot find what the function does, I assume that it turns something into an integer, and so I assume that this line maps box into a sequence of integers. However, box isn't a global or local variable either, only defined in the line itself, so It seems to be mapping nothing to nothing?

The next stage is as follows.

stage2 = [np.array(list(stage1) for box in line[1:]]

You've lost me here, turn into an array, the numpy (np is numpy) array of a list of everything of stage 1 for all boxes in the parameters from the 2nd item in the line array to the end? I'm not even sure that's a grammatically correct sentence.

What does this line of code in question exactly do? You can find the full code on this github page.

Prune
  • 76,765
  • 14
  • 60
  • 81
tuskiomi
  • 190
  • 1
  • 15
  • First, this is an excellent question that asks what a line of code does... Is it the [list comprehension](https://stackoverflow.com/questions/20639180/explanation-of-how-nested-list-comprehension-works) that is confusing? think of it as a for loop where box is what you're currently iterating on. You're right about int, its a [built in function](https://docs.python.org/3/library/functions.html#int) – Sayse Nov 01 '19 at 21:13
  • @Sayse the list function is confusing, as well as what data types are being passed into the functions. I've never like loose typing... :-/ – tuskiomi Nov 01 '19 at 21:19
  • Does https://stackoverflow.com/questions/9061760/how-to-read-aloud-python-list-comprehensions help? – Karl Knechtel Nov 01 '19 at 21:37

1 Answers1

4

You've seperated the line apart wrong, start from the outer point with the list comprehension in the form of

[          <code_that_gets_value>        for <element>  in  <iterable>]
[np.array(list(map(int,box.split(',')))) for    box      in   line[1:]]

The iterable

line[1:]

This just uses python slicing to get a list that is everything in line from the first index onwards (omits index 0 element)

The element

box

This is the element of the iterable that you're currently iterating on

Code that gets value

np.array(list(map(int,box.split(','))))

map is equivalent (similar but thats another story) to

 [int(x) for x in box.split(',')]

except in python 3, it returns a generator that needs converting into a list in order to be a valid parameter to go into the numpy array

The output of all of this is another list that then gets put into a numpy array. To be precise, its a 2 dimensional numpy array full of integers

Sayse
  • 42,633
  • 14
  • 77
  • 146
  • I'm running this in python 3, so does the last line change functionality? – tuskiomi Nov 01 '19 at 22:03
  • 1
    I do not think *iterator* is a good word choice, because it already means something else in Python. EDIT: In the grammar, it is merely called a ["target list"](https://docs.python.org/3/reference/expressions.html#grammar-token-comprehension). – juanpa.arrivillaga Nov 01 '19 at 22:27
  • 1
    Also note, `map` does *not* return a generator in Python 3, it returns *an iterator*. All generators are iterators, but not all iterators are generators. – juanpa.arrivillaga Nov 01 '19 at 22:30
  • @tuskiomi - the only difference in terms of python 2/3 is `map` already returned a list in python 2 so there was no need for `list()` – Sayse Nov 02 '19 at 06:05
  • @juanpa.arrivillaga - thanks! I've been using a lot of `yield` lately and confused myself.. (I never use map). I've changed it to element because target list still sounds like a crappy name to me – Sayse Nov 02 '19 at 06:14