12

What I am trying to do is pretty simple, but I couldn't find how to do it.

  • Starting with 1st element, put every 4th element into a new list.
  • Repeat with the 2nd, 3rd, and 4th elements.

From:

list = ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b']

To:

list1 = ['1', '5', '9']
list2 = ['2', '6', 'a']
list3 = ['3', '7', 'b']
list4 = ['4', '9']

In other words, I need to know how to:

  • Get the Nth element from a list (in a loop)
  • Store it in new arrays
  • Repeat
1
  • 1
    Don't generate new variables. Store your lists in a parent list instead. Commented Nov 15, 2014 at 11:26

4 Answers 4

23

The specific solution is to use slicing with a stride:

source = ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b']
list1 = source[::4]
list2 = source[1::4]
list3 = source[2::4]
list4 = source[3::4]

source[::4] takes every 4th element, starting at index 0; the other slices only alter the starting index.

The generic solution is to use a loop to do the slicing, and store the result in an outer list; a list comprehension can do that nicely:

def slice_per(source, step):
    return [source[i::step] for i in range(step)]

Demo:

>>> source = ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b']
>>> source[::4]
['1', '5', '9']
>>> source[1::4]
['2', '6', 'a']
>>> def slice_per(source, step):
...     return [source[i::step] for i in range(step)]
... 
>>> slice_per(source, 4)
[['1', '5', '9'], ['2', '6', 'a'], ['3', '7', 'b'], ['4', '8']]
>>> slice_per(source, 3)
[['1', '4', '7', 'a'], ['2', '5', '8', 'b'], ['3', '6', '9']]
Sign up to request clarification or add additional context in comments.

7 Comments

Why not make it a generator? It will handle the infinite case too then.
@EdgarKlerks: You'd have to make n islice iterators then.
@EdgarKlerks: which means you'd have to tee off the input iterable, and that could potentially become very expensive, memory wise.
@EdgarKlerks: it appears you were thinking of How do you split a list into evenly sized chunks in Python?..
@zertap the order is not altered, we select every 4th element in order. What you want is something different, you want to take fixed-size chunks, see What is the most "pythonic" way to iterate over a list in chunks?.
|
4

The numbered names are a bad idea, and you shouldn't name your own variable list (it shadows the built-in), but in general you can do something like:

>>> startlist = ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b']
>>> n = 4
>>> endlist = [[] for _ in range(n)]
>>> for index, item in enumerate(startlist):
    endlist[index % n].append(item)


>>> endlist
[['1', '5', '9'], ['2', '6', 'a'], ['3', '7', 'b'], ['4', '8']]

Comments

2
lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n']
s = []
n = 3
for x in range(n):
    s.append(lst[x::n])
    print(s)

1 Comment

An explanation is required for such an answer even if the explanation is one line long and consists roughly of one sentence. Consider updating your answer.
0

Alternative approach:

list = ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b']
lists = []
list_temp = []

for _, __ in enumerate(list, 1):
  list_temp.append(__)
  if _ % 3 == 0 or _ == len(list):
    lists.append(list_temp)
    list_temp = []

This will append the chunks in a temporary list and append the temporary list to our final list every time the index divided by the desired list length has no remainders.

It’s more a mathematical approach than a pythonic one :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.