2

I have a line of code like this:

list1=[string1[i:i+int1] for i in range(0, len(string1), int1)] 

I remember my teacher saying that we should start new lines when there is 'for' so, is there a way to write this code that looks like:

for i in range(0, len(string1), int1): #something here 

or something else?

4
  • 8
    Please read about list comprehensions. Commented Apr 4, 2016 at 14:13
  • 8
    Your teacher's advice is an oversimplification. You should start a new line when there is a for statement, but a for inside of an expression isn't part of a for statement; it's part of a list comprehension. Commented Apr 4, 2016 at 14:14
  • 3
    I'm almost certain your teacher didn't mean you should forgo all list comprehensions in favor of explicitly for loops that build a list piecemeal. If they did, they aren't really teaching you Python. Commented Apr 4, 2016 at 14:15
  • No doubt your teacher was trying to simplify things. I'll update your title to the question that you're actually asking here. Commented Apr 4, 2016 at 14:20

5 Answers 5

5

You mean to extract a boring old regular for loop from a list-comprehension?

list1=[string1[i:i+int1] for i in range(0, len(string1), int1)] 

Becomes:

list1 = list() for i in range(0, len(string1), int1): list1.append(string1[i:i+int1]) 

This would be useful if you wanted to add exception handling, logging, or more complex functions or behaviors while you iterate over your data.

For instance:

list1 = list() for i in range(0, len(string1), int1): log.info('in loop: i={}'.format(i)) try: data = string1[i:i+int1] except: log.error('oh no!') # maybe do something complex here to get some data anyway? data = complex_function(i) log.debug('appending to list: data={}'.format(data)) list1.append(data) 

But generally speaking the list-comprehension is a totally legitimate way to write that.

Sign up to request clarification or add additional context in comments.

4 Comments

alternatively, one could write a function and do [somefunction(val) for val in values]. Assuming that was appropriate for the case, of course. As another potentially appropriate alternative, rather than returning a list, one could yield data and get a generator out of the deal.
[] is more efficient than list(). See why
@zondo: Also conveniently avoids the problem of people name-shadowing list, though ideally, they wouldn't do that in the first place. :-) That said, the incremental cost of list() over [] is pretty small, about 60-70 extra ns on my machine (admittedly an increase of 2-3.5x over the base cost of [] of ~20-30 ns, but unlikely to matter in all but the hottest of loops).
I'd add readability to that. something = [] is more immediately recognisable than something = list() to me.
3

You have to create the empty list first, and then append for each iteration.

list1 = [] for i in range(0, len(string1), int1): list1.append(string1[i:i+int1]) 

Comments

1

That list comprehension would translate to:

l = [] for i in range(0, len(string1), int1): l.append(string1[i:i+int1]) 

Comments

0

Little bit dirty, but a good alternative for splitting collection to subcollections of a fixed size.

from itertools import zip_longest l = [] for chunk in zip_longest(*([iter(string1)]*int1), fillvalue=''): l.append(''.join(chunk)) 

Comments

0
g = (string[i:i+int1] for i,char in enumerate(string) if i % int1 == 0) l = list(g) 

Do not use len(iterable) in the while dealing with indices. Use enumerate() for that. It yields (index, item). This is efficient and pythonic.

The idea that you should make a newline while using for loop is probably idiomatic to some other language, C, C++ e.g. But not in python. List comprehensions come fro the Haskell world of FP. So that's elegant as they come.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.