3

the following two loop-constructs are basically the same. I just can't figure out how to insert two variables start = start+2 and end = end+2 inside the first syntax. Thank you

FIRST CONSTRUCT (list comprehension):

start = 1
end = 3    

clips = [ImageClip(os.path.join(folder,pic))
         .resize(width=w*9.3/16)
         .set_start(start)
         .set_end(end)
         .set_pos(lambda t:(max((402), (int(w-3*w*t))), "center"))
         for pic in picfiles]

SECOND CONSTRUCT (regular loop):

start = 1
end = 3
clips = []
for pic in picfiles:
    clips.append(ImageClip(os.path.join(folder,pic))
                 .resize(width=w*9.3/16)
                 .margin(left=31, opacity=0)
                 .set_start(start)
                 .set_end(end)
                 .set_pos(lambda t:(max((402), (int(w-3*w*t))), "center")) # move from right to center
                 )

    start = start + 2
    end = end + 2
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
Anay Bose
  • 880
  • 1
  • 14
  • 24
  • 2
    [How can I do assignments in a list comprehension?](http://stackoverflow.com/questions/10291997/how-can-i-do-assignments-in-a-list-comprehension) – ayhan Jun 04 '16 at 20:21
  • 2
    For a list comprehension to have side effects in very... unusual style. I would recommend avoiding it, at minimum as a service to your code's readers. – Charles Duffy Jun 04 '16 at 20:23

1 Answers1

3

There are many way to do it. For instance, you can do something such as:

clips = [
ImageClip(os.path.join(folder,pic))
         .resize(width=w*9.3/16)
         .set_start(index*2+1)
         .set_end(index*2+3)
         .set_pos(lambda t:(max((402), (int(w-3*w*t))), "center"))

    for index, pic in enumerate(picfiles)
]

It uses the function enumerate. Here's an example showing it works.

list(enumarate(['a','b','c'])) = ((1, 'a'), (2, 'b'), (3, 'c'))

However, you should be very aware when using that kind of structure as it can lead sometimes to incomprehensible formulas. For your code, I think it's OK but when you are doing more complicated computations, regular loops are often cleaner.

You can also use that construction if your other values are uncorrelated (as in your example there was a simple relation between the loop indice, start and stop).

[obj.setStart(start).setStop(stop) for obj, start, stop in objects, starts, stops]

Where you can define starts and stops the way you want. In your specific problem, it should be:

clips = [
ImageClip(os.path.join(folder,pic))
         .resize(width=w*9.3/16)
         .set_start(start)
         .set_end(stop)
         .set_pos(lambda t:(max((402), (int(w-3*w*t))), "center"))

    for start, stop, pic in 
    (
        itertools.count(1, step=2),
        itertools.count(3, step=2),
        enumerate(picfiles)
    )
]
Alexis Clarembeau
  • 2,776
  • 14
  • 27