Как разделить список на части python

от admin

Разделите список на куски заданного размера в Python

В этом посте будет обсуждаться, как разбить список на куски заданной длины. n в Python.

Input: [1, 2, 3, 4], n = 2

результат: [[1, 2], [3, 4]]

Если длина последовательности не делится без остатка на заданную длину, мы должны заполнить последний раздел остатками элементов.

Input: [1, 2, 3, 4, 5], n = 2

результат: [[1, 2], [3, 4], [5]]

Ниже приведены различные способы разделения списка на фрагменты равной длины в Python:

1. Использование нарезки

Простое решение состоит в том, чтобы написать генератор, который последовательно выдает фрагменты заданного размера из списка. Этого легко добиться с помощью нарезки, как показано ниже:

Python: Split a List (In Half, in Chunks)

In this tutorial, you’ll learn how to use Python to split a list, including how to split it in half and into n equal-sized chunks. You’ll learn how to split a Python list into chunks of size n , meaning that you’ll return lists that each contain n (or fewer if there are none left) items. Knowing how to work with lists in Python is an important skill to learn.

By the end of this tutorial, you’ll have learned:

  • How to split a list in half in Python
  • How to split a list into chunks in Python
  • How to split a list at a particular index position in Python
  • How to use NumPy to split a list in Python

The Quick Answer: Use List Indexing to Split a List in Python

Quick Answer - Split a Python List into Chunks

Table of Contents

How to Access a Python List by Its Index

One of the many wonderful properties of lists is that they are ordered. This means that we can access an item, or a range of items, by its index. Let’s see how Python list indices work:

How does Python List Indexing Work

We can see here that Python lists have both a positive index as well as a negative index. A positive index begins at position 0, meaning the first item. A negative list index begins at -1, allowing you to retrieve the last item of a list.

Similarly, you can access ranges of data within a list using list slicing. This can be done by using the : colon character, which allows you to select items from a specific position up to a specific position.

How to Split a Python List in Half

You can easily split a Python list in half using list indexing. As you learned above, you can select multiple items in a list using list slicing. Let’s see how we can use list slicing to split a list in half:

Let’s break down what we did in the code above:

  1. We created a list a_list , which contains ten different items
  2. We then created an integer variable, half_length , which is the result of dividing the length of the list by two using integer division
  3. We then assigned variables, first_half and second_half , which sliced the lists up to and from the half variable

In the following section, you’ll learn how to split a list into different sized chunks in Python.

Split Lists into Chunks Using a For-Loop

For-loops in Python are an incredibly useful tool to use. They make a lot of Python methods easy to implement, as well as easy to understand. For this reason, let’s start off by using a for-loop to split our list into different chunks.

One of the ways you can split a list is into n different chunks. Let’s see how we can accomplish this by using a for loop:

Let’s take a look at what we’ve done here:

  1. We instantiate two lists: a_list , which contains the items of our original list, and chunked_list , which is empty
  2. We also declare a variable, chunk_size , which we’ve set to three, to indicate that we want to split our list into chunks of size 3
  3. We then loop over our list using the range function. What we’ve done here is created items from 0, through to the size of our list, iterating at our chunk size. For example, our range function would read range(0, 11, 3) , meaning that we’d loop over using items 0,3,6,9 .
  4. We then index our list from i:i+chunk_size , meaning the first loop would be 0:3 , then 3:6 , etc.
  5. These indexed lists are appended to our list

We can see that this is a fairly straightforward way of breaking a Python list into chunks. Next, you’ll learn how to do accomplish this using Python list comprehensions.

Split Python Lists into Chunks Using a List Comprehension

In many cases, Python for-loops can be rewritten in a more Pythonic way by writing them as one-liners called list comprehensions. List comprehensions in Python have a number of useful benefits over for-loops, including not having to instantiate an empty list first, and not having to break your for-loop over multiple lines.

Let’s see how we can write a Python list comprehension to break a list into chunks:

Before we break down this code, let’s see what the basic syntax of a Python list comprehension looks like:

Python List Comprehensions Syntax

Now let’s break down our code to see how it works:

  1. We declare a variable chunk_size to determine how big we want our chunked lists to be
  2. For our list comprehensions expression, we index our list based on the i th to the i+chunk_size th position
  3. We use this expression to iterate over every item in the output of the range() object that’s created based on range(0, len(our_list), chunk_size , which in this case would be 0,3,6,9

While this approach is a little faster to type, whether or not it is more readable than a for-loop, is up for discussion. Let’s learn how to split our Python lists into chunks using numpy.

Want to learn more? Check out my in-depth tutorial about Python list comprehensions by clicking here!

Split Lists into Chunks Using NumPy

Numpy is an amazing Python library that makes mathematical operations significantly easier. That being said, NumPy also works with a list-like object, called NumPy arrays, that make working with lists much easier. These NumPy arrays come packaged with lots of different methods to manipulate your arrays.

It’s important to note that this method will only work with numeric values.

In this section of the tutorial, we’ll use the NumPy array_split() function to split our Python list into chunks. This function allows you to split an array into a set number of arrays.

Let’s see how we can use NumPy to split our list into 3 separate chunks:

This is a fairly long way of doing things, and we can definitely cut it down a little bit. Let’s see how that can be done:

Let’s break this down a little bit:

  1. We turn our list into a Numpy array
  2. We split our array into n number of arrays using the np.array_split() function
  3. Finally, we use a list comprehension to turn all the arrays in our list of arrays back into lists.

Want to learn more about division in Python? Check out my tutorial on how to use floored integer division and float division in Python in this tutorial here.

Split Lists into Chunks Using Itertools

Let’s see how we can use itertools library to split a list into chunks. In particular, we can use the zip_longest function to accomplish this.

Читать:
Fltk org что это за папка

Let’s see how we can do this:

We can see here that we can have a relatively simple implementation that returns a list of tuples. Notice one of the things that are done here is split the list into chunks of size n, rather than into n chunks.

Frequently Asked Questions

The best way to split a Python list is to use list indexing, as it gives you huge amounts of flexibility.

The NumPy array_split() function allows you to easily split arrays into a given number of arrays. However, the function only works with numeric values (as NumPy arrays can only contain numeric values).

Conclusion

In this post, you learned how to split a Python list into chunks. You learned how to accomplish splitting a Python list into chunks of size n or into n number chunks . You learned how to do this using a for-loop, using list comprehensions, NumPy and itertools.

How do I split a list into equally-sized chunks?

How do I split a list of arbitrary length into equal sized chunks?

See How to iterate over a list in chunks if the data result will be used directly for a loop, and does not need to be stored.

For the same question with a string input, see Split string every nth character?. The same techniques generally apply, though there are some variations.

66 Answers 66

Here’s a generator that yields evenly-sized chunks:

For Python 2, using xrange instead of range :

Below is a list comprehension one-liner. The method above is preferable, though, since using named functions makes code easier to understand. For Python 3:

Mateen Ulhaq's user avatar

Something super simple:

For Python 2, use xrange() instead of range() .

Mateen Ulhaq's user avatar

I know this is kind of old but nobody yet mentioned numpy.array_split :

Mateen Ulhaq's user avatar

Directly from the (old) Python documentation (recipes for itertools):

The current version, as suggested by J.F.Sebastian:

I guess Guido’s time machine works—worked—will work—will have worked—was working again.

These solutions work because [iter(iterable)]*n (or the equivalent in the earlier version) creates one iterator, repeated n times in the list. izip_longest then effectively performs a round-robin of «each» iterator; because this is the same iterator, it is advanced by each such call, resulting in each such zip-roundrobin generating one tuple of n items.

I’m surprised nobody has thought of using iter ‘s two-argument form:

This works with any iterable and produces output lazily. It returns tuples rather than iterators, but I think it has a certain elegance nonetheless. It also doesn’t pad; if you want padding, a simple variation on the above will suffice:

Like the izip_longest -based solutions, the above always pads. As far as I know, there’s no one- or two-line itertools recipe for a function that optionally pads. By combining the above two approaches, this one comes pretty close:

I believe this is the shortest chunker proposed that offers optional padding.

As Tomasz Gandor observed, the two padding chunkers will stop unexpectedly if they encounter a long sequence of pad values. Here’s a final variation that works around that problem in a reasonable way:

senderle's user avatar

Here is a generator that work on arbitrary iterables:

Simple yet elegant

or if you prefer:

kevinarpe's user avatar

Don’t reinvent the wheel.

UPDATE: The upcoming Python 3.12 introduces itertools.batched , which solves this problem at last. See below.

Given

Code

(or DIY, if you want)

The Standard Library

References

    (related posted) (related post) (see also stagger , zip_offset ) (related post, related post) (ordered results requires Python 3.6+) (ordered results requires Python 3.6+)

+ A third-party library that implements itertools recipes and more. > pip install more_itertools

++ Included in Python Standard Library 3.12+. batched is similar to more_itertools.chunked .

pylang's user avatar

How do you split a list into evenly sized chunks?

"Evenly sized chunks", to me, implies that they are all the same length, or barring that option, at minimal variance in length. E.g. 5 baskets for 21 items could have the following results:

A practical reason to prefer the latter result: if you were using these functions to distribute work, you’ve built-in the prospect of one likely finishing well before the others, so it would sit around doing nothing while the others continued working hard.

Critique of other answers here

When I originally wrote this answer, none of the other answers were evenly sized chunks — they all leave a runt chunk at the end, so they’re not well balanced, and have a higher than necessary variance of lengths.

For example, the current top answer ends with:

Others, like list(grouper(3, range(7))) , and chunk(range(7), 3) both return: [(0, 1, 2), (3, 4, 5), (6, None, None)] . The None ‘s are just padding, and rather inelegant in my opinion. They are NOT evenly chunking the iterables.

Why can’t we divide these better?

Cycle Solution

A high-level balanced solution using itertools.cycle , which is the way I might do it today. Here’s the setup:

Now we need our lists into which to populate the elements:

Finally, we zip the elements we’re going to allocate together with a cycle of the baskets until we run out of elements, which, semantically, it exactly what we want:

Here’s the result:

To productionize this solution, we write a function, and provide the type annotations:

In the above, we take our list of items, and the max number of baskets. We create a list of empty lists, in which to append each element, in a round-robin style.

Slices

Another elegant solution is to use slices — specifically the less-commonly used step argument to slices. i.e.:

This is especially elegant in that slices don’t care how long the data are — the result, our first basket, is only as long as it needs to be. We’ll only need to increment the starting point for each basket.

In fact this could be a one-liner, but we’ll go multiline for readability and to avoid an overlong line of code:

And islice from the itertools module will provide a lazily iterating approach, like that which was originally asked for in the question.

I don’t expect most use-cases to benefit very much, as the original data is already fully materialized in a list, but for large datasets, it could save nearly half the memory usage.

View results with:

Updated prior solutions

Here’s another balanced solution, adapted from a function I’ve used in production in the past, that uses the modulo operator:

And I created a generator that does the same if you put it into a list:

And finally, since I see that all of the above functions return elements in a contiguous order (as they were given):

Output

To test them out:

Which prints out:

Notice that the contiguous generator provide chunks in the same length patterns as the other two, but the items are all in order, and they are as evenly divided as one may divide a list of discrete elements.

Python-сообщество

In : def chunks(lst, count):
…: n = len(lst) // count
…: return list(x for x in zip_longest(* * n))
…:

как таким-же образом разбить список на N частей не используя функцию zip_longest
старый python 2.6 отказывается импортировать её… а другой поставить на solaris пока-что не могу…
P.s. не обращайте пожалуйста внимание на фигурные скобки — если ставить квадратные в форуму почему-то исчезает текст

Похожие статьи