2

There are too many questions of list comprehensions on this website, but none seem to match what I'd like to do. I have already done it with a for loop, but I was wondering if it could be done with list comprehensions, or if someone could direct me where I could find a similar case.

I have a list of functions:

function_list=[iron,cobalt,nickel,copper,zinc,vanadium,chromium,managenese,titanium,footer]

Each function is a question I ask to my students, exported to a PDF file. The last function on the list, is footer which makes the PDF file insert a page skip to the next page.

So usually, What does a simple quiz look like (so far)?

call_functions([x for x in function_list[0:3]] + [function_list[-1]])

generating

call_functions([iron,cobalt,nickel,footer]) #as desired

where call_functions is basically a PDF exporter. So my list comprehension adds three questions and skips to the next page, adding three more. As the number of questions grow, the code ends up looking like a mess:

call_functions([x for x in function_list[0:3]] + [function_list[-1]] + [x for x in function_list[3:6]]+ [function_list[-1]] + [x for x in function_list[6:9]])

generating

call_functions([iron,cobalt,nickel,footer,copper,zinc,vanadium,footer,chromium,managenese,titanium]) #as desired

although this works, I'm trying to make a single comprehension list that will iterate through the list and after every third element, it'll insert the last element on the list. Or even keep footer outside the list is also viable. But I can't get it to work.

I've tried:

[x for i,x in enumerate(function_list[0:9]) if i%3==0 function_list[-1] else x]

to SyntaxError.

Also tried:

[x if i%3==0 function_list[-1] else x for i,x in enumerate(function_list[0:9])]

Also to SyntaxError

Could someone tell me (or direct me to) what am I doing wrong, and/or direct to a similar case, please?

Thanks

The Exabot
  • 21
  • 2
  • is this the answer? https://stackoverflow.com/questions/18272160/access-multiple-elements-of-list-knowing-their-index – Chris_Rands Sep 24 '19 at 14:47
  • 1
    general point `[x for x in function_list[0:3]` is just `function_list[:3]` – Chris_Rands Sep 24 '19 at 14:48
  • 1
    Regular for-loop will be more readable and less error prone. So maybe striving for list comprehension is what you actually doing wrong? –  Sep 24 '19 at 14:54
  • @Poolka The more I dig into list comprehensions on my particular case, the more I think you're right. But well, it was worth the try. Thanks! – The Exabot Sep 24 '19 at 15:59

2 Answers2

2
[func for i in range(0, len(function_list) - 1, 3) for func in function_list[i:i+3] + [function_list[-1]]]

output:

>>>

['iron',
 'cobalt',
 'nickel',
 'footer',
 'copper',
 'zinc',
 'vanadium',
 'footer',
 'chromium',
 'managenese',
 'titanium',
 'footer']
Brian
  • 1,572
  • 9
  • 18
  • This seems to have an unwanted flatten. – Dan D. Sep 24 '19 at 15:38
  • @DanD. , OP listed: `[iron,cobalt,nickel,footer,copper,zinc,vanadium,footer,chromium,managenese,titanium] #as desired` which is flattened so I flattened it. My originial answer actually didn't include the flatten if you think that's what was desired: `[function_list[i:i+3] + [function_list[-1]] for i in range(0, len(function_list) - 1, 3)]` – Brian Sep 24 '19 at 15:44
  • This is indeed a nice alternative! Thanks! – The Exabot Sep 24 '19 at 15:52
0

Nevermind, I think I got it to work.

What worked for me was the following:

call_functions([x if (i+1)%4!=0 else function_list[-1] for i,x in enumerate(function_list)])

If I do

if i%4!=0 #making the fourth element function footer

I get a list that starts with the footer function. But doing:

if (i+1)%4!=0

I avoid the initial issue. I get:

call_functions([iron,cobalt,nickel,footer,copper,zinc,vanadium,footer,chromium,managenese,titanium,footer])

I'm sure there must be other ways to do this simpler and neater, any suggestions welcome.

Thanks!

Ex.

The Exabot
  • 21
  • 2