Problem with list.remove() method

A

Alvaro Combo

Hi All,

I'm relatively new to Python... but I have found something I cannot explain... and I'm sure you can help me.

I have the following function that serves for removing the duplicates from a list... It's a simple and (almost) trivial task.

I'm using WingIDE as editor/debugger and have Python 2.7.3.

When running this I have an error when trying to remove cpy_lst[4]... and ONLY THAT!!! Even in interactive mode!!!

Any suggestion is MOST welcome.

Best Regards

ACombo

....And the code:

def remove_dup_5_10():
"""
Remove the duplicates of a given list. The original list MUST be kept.
"""

# Set the original list
lst = ['a', 1, 10.0, 2, 'd', 'b', 'b', 'b', 1, 2, 'b' ]

# NEED to create a copy... See dicussion on Problem 5.6 and issue #2
cpy_lst = list(lst)

# Perform an infinite loop... explained later
i=0 # initialize the index
while i != len(cpy_lst):
if cpy_lst.count(cpy_lst) != 1:
cpy_lst.remove(i)
else:
i += 1

print "The original List: ", lst
print "List with NO duplicates: ", cpy_lst

return True
 
C

Chris Angelico

Hi All,

I'm relatively new to Python... but I have found something I cannot explain... and I'm sure you can help me.

I have the following function that serves for removing the duplicates from a list... It's a simple and (almost) trivial task.

I'm using WingIDE as editor/debugger and have Python 2.7.3.

When running this I have an error when trying to remove cpy_lst[4]... and ONLY THAT!!! Even in interactive mode!!!

Several points here. You've written a beautiful O(N^2) duplicates
remover... Python has a really fast way of doing it, if you don't mind
losing order:

cpy_lst = list(set(lst))

But let's assume you're doing this for the exercise. Your technique is
fine, if inefficient on large lists, but the remove() method looks for
the first occurrence of an element by its value - what you want is:

del cpy_lst

which will remove one element by index.

With that change, you'll have a slightly odd duplicate remover that
keeps the *last* of any given element. That's rather unusual. Instead,
you may want to consider maintaining a set of "items I've already
seen", and keeping all elements that aren't in that set. I won't give
you all the code, but here's the basic set operations:

sighted = set()
sighted.add(some_element)
if some_element in sighted: # condition is True if you've already
seen this element

Hope that helps!

ChrisA
 
A

Alvaro Combo

Dear Chris,

Thank you very much for you reply...
For a newcomer to Python the Hell is in the details... :).

You are absolutely right... and I just used the index instead of the value.

Regarding you other (most relevant) comments, I absolutely agree... BUT in those cases... I was aware :). But since it is in fact an exercise... and having N^2 operations... is not important. Still your comments are quite pertinent.

Once again, Thank you and best regards

ACombo
 
A

Alvaro Combo

Dear Chris,

Thank you very much for you reply...
For a newcomer to Python the Hell is in the details... :).

You are absolutely right... and I just used the index instead of the value.

Regarding you other (most relevant) comments, I absolutely agree... BUT in those cases... I was aware :). But since it is in fact an exercise... and having N^2 operations... is not important. Still your comments are quite pertinent.

Once again, Thank you and best regards

ACombo
 
T

Terry Reedy

Hi All,

I'm relatively new to Python... but I have found something I cannot explain... and I'm sure you can help me.

I have the following function that serves for removing the duplicates from a list... It's a simple and (almost) trivial task.

I'm using WingIDE as editor/debugger and have Python 2.7.3.

When running this I have an error when trying to remove cpy_lst[4]... and ONLY THAT!!! Even in interactive mode!!!

Several points here. You've written a beautiful O(N^2) duplicates
remover... Python has a really fast way of doing it, if you don't mind
losing order:

cpy_lst = list(set(lst))

But let's assume you're doing this for the exercise. Your technique is
fine, if inefficient on large lists, but the remove() method looks for
the first occurrence of an element by its value - what you want is:

del cpy_lst

which will remove one element by index.

With that change, you'll have a slightly odd duplicate remover that
keeps the *last* of any given element. That's rather unusual. Instead,
you may want to consider maintaining a set of "items I've already
seen", and keeping all elements that aren't in that set. I won't give
you all the code, but here's the basic set operations:

sighted = set()
sighted.add(some_element)
if some_element in sighted: # condition is True if you've already
seen this element


The itertools doc, in the last section, has a recipe for this problem
that uses the above approach.
 
P

Prasad, Ramit

Alvaro said:
Hi All,

I'm relatively new to Python... but I have found something I cannot explain... and I'm sure you can help me.

I have the following function that serves for removing the duplicates from a list... It's a simple and (almost)
trivial task.

I'm using WingIDE as editor/debugger and have Python 2.7.3.

When running this I have an error when trying to remove cpy_lst[4]... and ONLY THAT!!! Even in interactive
mode!!!

Any suggestion is MOST welcome.

Best Regards

ACombo

...And the code:

def remove_dup_5_10():
"""
Remove the duplicates of a given list. The original list MUST be kept.
"""

# Set the original list
lst = ['a', 1, 10.0, 2, 'd', 'b', 'b', 'b', 1, 2, 'b' ]

# NEED to create a copy... See dicussion on Problem 5.6 and issue #2
cpy_lst = list(lst)

# Perform an infinite loop... explained later
i=0 # initialize the index
while i != len(cpy_lst):
if cpy_lst.count(cpy_lst) != 1:
cpy_lst.remove(i)
else:
i += 1

print "The original List: ", lst
print "List with NO duplicates: ", cpy_lst

return True
--


Remove looks for the *value*not the *index* of the value.

Helpon built-in function remove:

remove(...)
L.remove(value) -- remove first occurrence of value.
Raises ValueError if the value is not present.

Change ` cpy_lst.remove(i)` to `cpy_lst.remove(cpy_lst)`.

~Ramit



This email is confidential and subject to important disclaimers and
conditions including on offers for the purchase or sale of
securities, accuracy and completeness of information, viruses,
confidentiality, legal privilege, and legal entity disclaimers,
available at http://www.jpmorgan.com/pages/disclosures/email.
 
C

Chris Angelico

Dear Chris,

Thank you very much for you reply...
For a newcomer to Python the Hell is in the details... :).

You're most welcome! As Adam Savage of Mythbusters is fond of saying
(with an exaggerated accent), "It's all a learning experience".
Regarding you other (most relevant) comments, I absolutely agree... BUT in those cases... I was aware :). But since it is in fact an exercise... and having N^2 operations... is not important. Still your comments are quite pertinent.

Yep. O(N^2) isn't inherently a problem, it just means that the
technique will scale poorly to large numbers of list elements. With
small lists, it'll be "fast enough" - for all intents and purposes,
the bulk of Python code executes in zero time, despite being in an oh
so slow interpreted language and using ridiculously inefficient (but
beautifully readable) code. That's the beauty of modern hardware :)

However, I do think that people should be aware when they're writing
non-scaleable code. That's not just algorithmic complexity; if you're
making a system that won't handle more than one request a second
(because, for instance, it uses seconds-since-1970 as a request
identifier), that's something worth being aware of, even if it's
unlikely ever to be a problem. Just know, so that if a problem ever
_does_ occur, you know where it is!

ChrisA
 
D

Dennis Lee Bieber

...And the code:

def remove_dup_5_10():
"""
Remove the duplicates of a given list. The original list MUST be kept.
"""

# Set the original list
lst = ['a', 1, 10.0, 2, 'd', 'b', 'b', 'b', 1, 2, 'b' ]

# NEED to create a copy... See dicussion on Problem 5.6 and issue #2
cpy_lst = list(lst)

Why copy the source list at the start and then...
# Perform an infinite loop... explained later
i=0 # initialize the index
while i != len(cpy_lst):
if cpy_lst.count(cpy_lst) != 1:
cpy_lst.remove(i)


.... remove elements from the copy...

else:
i += 1

print "The original List: ", lst
print "List with NO duplicates: ", cpy_lst

Wouldn't it be simpler to just add each NON-duplicate of the source
to the destination?

dest = []
for itm in source:
if itm not in dest:
dest.append(itm)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,815
Latest member
treekmostly22

Latest Threads

Top