473,699 Members | 2,321 Online

# spliting a list by nth items

I feel like this has probably been answered before, but I couldn't
find something quite like it in the archives. Feel free to point me

I have a list in a particular order that I want to split into two
lists: the list of every nth item, and the list of remaining items.
It's important to maintain the original order in both lists.

So the first list is simple:

nth_items = items[::n]

The second list is what's giving me trouble. So far, the best I've
come up with is:

non_nth_items = list(items)
del non_nth_items[::n]

Is this the right way to do this?

Steve
--
You can wordify anything if you just verb it.
- Bucky Katt, Get Fuzzy
Jul 18 '05 #1
33 3009
Steven Bethard wrote:
I feel like this has probably been answered before, but I couldn't
find something quite like it in the archives. Feel free to point me

I have a list in a particular order that I want to split into two
lists: the list of every nth item, and the list of remaining items.
It's important to maintain the original order in both lists.

So the first list is simple:

nth_items = items[::n]

The second list is what's giving me trouble. So far, the best I've
come up with is:

non_nth_items = list(items)
del non_nth_items[::n]

Is this the right way to do this?

There's probably no "right" way. Your way isn't the way I
would have thought to do it, I think. But it's brilliant. :-)
(Also simple and clear.)

-Peter
Jul 18 '05 #2
Steven Bethard wrote:
I have a list in a particular order that I want to split into two
lists: the list of every nth item, and the list of remaining items.
It's important to maintain the original order in both lists.

So the first list is simple:

nth_items = items[::n]

The second list is what's giving me trouble.

non_nth_items = [x for x in items if x % n]
--
Michael Hoffman
Jul 18 '05 #3
I believe you meant somthing like:

non_nth_items = [items[i-1] for i in range(1,len(ite ms)-1) if i % n]

I don't think the "if x % n" won't work on his list of items

Larry Bates

"Michael Hoffman" <m.************ *************** ******@example. com> wrote in
message news:ci******** **@pegasus.csx. cam.ac.uk...
Steven Bethard wrote:
I have a list in a particular order that I want to split into two
lists: the list of every nth item, and the list of remaining items. It's
important to maintain the original order in both lists.

So the first list is simple:

nth_items = items[::n]

The second list is what's giving me trouble.

non_nth_items = [x for x in items if x % n]
--
Michael Hoffman

Jul 18 '05 #4
Larry Bates wrote:
I believe you meant somthing like:

non_nth_items = [items[i-1] for i in range(1,len(ite ms)-1) if i % n]

I don't think the "if x % n" won't work on his list of items

D'oh! I wasn't thinking--the test list of items I used was
range(something ), so of course it worked.

What I meant <wink> was:

non_nth_items = [x for index, x in enumerate(items ) if index % n]

Thanks for the correction.
--
Michael Hoffman
Jul 18 '05 #5
Larry Bates <lbates <at> swamisoft.com> writes:

I believe you meant somthing like:

non_nth_items = [items[i-1] for i in range(1,len(ite ms)-1) if i % n]

Yeah, the items list is not of the form range(x) -- in fact, my current use
for this is with a list of filenames -- so Michael Hoffman's solution:
non_nth_items = [x for x in items if x % n]

wouldn't work. In the full fledged problem, I actually have a start parameter
for the slice as well as the step parameter (n), so I could probably do
something along these lines (inspired by your two suggestions):

non_nth_items = [item for i, item in enumerate(items ) if (i - start) % n]

non_nth_items = list(items)
del non_nth_items[start::n]

The enumerate/range solution is a little more verbose, but it does only go
through the list once. Thanks for the good suggestions!

STeve
Jul 18 '05 #6
[Steven Bethard]
so I could probably do
something along these lines (inspired by your two suggestions):

non_nth_items = [item for i, item in enumerate(items ) if (i - start) % n]

non_nth_items = list(items)
del non_nth_items[start::n]

The enumerate/range solution is a little more verbose, but it does only go
through the list once. Thanks for the good suggestions!

The enumerate solution has a lot going for it. It is more flexible and easily
accomodates criteria other than every nth item. More importantly, it
demonstrates an important guiding principle: multiple list deletions are a code
smell indicating that building a new list is a better approach. On this
newsgroup, I've seen people tie themselves in knots with multiple in-place
deletions during iteration when the new list approach was clearer, more robust,
and faster.

The runtime behavior of the non_nth_items[start::n] approach is implementation
dependent. One can easily imagine a O(n**2) process running behind the scenes.
CPython is a smarter than that, but the code for list_ass_subscr ipt() in
listobject.c is not a pretty sight.
Raymond Hettinger
Jul 18 '05 #7
Raymond Hettinger writes:
The enumerate solution has a lot going for it. It is more flexible and
easily accomodates criteria other than every nth item.
items[start::n]
to make the nth_items list in the first place. (If I was planning to allow
for other criteria, I'd probably use filter or ifilter instead of the
slicing...)
More importantly, it demonstrates an important guiding principle: multiple
list deletions are a code smell indicating that building a new list is a
better approach.
This was kinda my feeling -- hence why I posted. Part of the problem for me
was that because the two lists were so closely related semantically, I was
looking for a syntax that was also closely related. Sometimes this is a good
intuition to have, sometimes not. ;)
The runtime behavior of the non_nth_items[start::n] approach is
implementation dependent.

Ahh, I didn't know that. Good thing to know...

Thanks,

Steve

Jul 18 '05 #8
>>> x = [0,1,2,3,4,5,6,7 ,8,9]
n = 3
y = [x[i] for i in range(len(x)) if i%n==0]
z = [x[i] for i in range(len(x)) if i%n<>0]
x [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] y [0, 3, 6, 9] z

[1, 2, 4, 5, 7, 8]
"Steven Bethard" <st************ @gmail.com> wrote in message
news:ma******** *************** *************** @python.org...
| I feel like this has probably been answered before, but I couldn't
| find something quite like it in the archives. Feel free to point me
|
| I have a list in a particular order that I want to split into two
| lists: the list of every nth item, and the list of remaining items.
| It's important to maintain the original order in both lists.
|
| So the first list is simple:
|
| nth_items = items[::n]
|
| The second list is what's giving me trouble. So far, the best I've
| come up with is:
|
| non_nth_items = list(items)
| del non_nth_items[::n]
|
| Is this the right way to do this?
|
| Steve
| --
| You can wordify anything if you just verb it.
| - Bucky Katt, Get Fuzzy
Jul 18 '05 #9
I was one of the frequent posters on the many tools/ides/gui threads
that appeared here over the past weeks. I'm now partly satisfied. My
search for a good IDE that is usable in my lowend machine is still not
completed. But I found a good setup using a free editor and PythonWin
working together.

I'm using Crimson Editor, a small freeware editor. The most
interesting part is that it isn't the most featured of all editors
I've tried; it isn't as powerful as vi or emacs, but has one feature
that I wanted the most, that is a fairly simple project management
tool. It simply allows me to organize a list of files that I'm using
for a project on the left pane. I can click on a file to open it. It's
amazingly useful when you're dealing with "hot" files stored on
several different directories, and you don't have to remember where is
it located, or to manually walk the open file dialog looking for it.

I'm using PythonWin for testing, mostly because the Windows console is
so braindead, and because PythonWin help is quick well organized (it's
about the same that you find in the web, but a little bit more
convenient).

I'm also evaluating Wing IDE 2.0; I had a few issues with it that were
solved, but for some tasks I found it too heavy for my limited
resources. Anyway, I'm keeping an eye on it.

--
http://mail.python.org/mailman/listinfo/python-list

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmai l.com
mail: ca********@yaho o.com
Jul 18 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.