I'm befuddled by something. Here is transcript of the interactive session:

>>> range(9).remove(3)
>>>
>>> print range(9).remove(3)
None
>>> a = range(9).remove(3)
>>> a
>>> a = range(9)
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8]
>>> a.remove(3)
>>> a
[0, 1, 2, 4, 5, 6, 7, 8]
>>> a = list(range(9)).remove(3)
>>> a
>>> a  = list(range(9))
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8]
>>> a.remove(3)
>>> a
[0, 1, 2, 4, 5, 6, 7, 8]
>>> a = [range(9)].remove(3) # getting desperate here

Traceback (most recent call last):
  File "<pyshell#17>", line 1, in -toplevel-
    a = [range(9)].remove(3)
ValueError: list.remove(x): x not in list

No matter what I do, I can't seem to get the concept range(9).remove(3) to perform properly in one line. Contrast this with something like:

>>> s = 'Hi there \n'
>>> s.strip().split(" ")
['Hi', 'there']

So why does it matter? I'm trying to allow the user to edit a list of items, and when he's done, I need to check the list to make sure that he hasn't accidentally duplicated an item on the list. The items are complex objects, where some properties count for identity and some don't, so the basic resulting code (if there's an easier way, tip me off!) was

if True in [item.is_same(x) for x in data_list]:
  print "on list already"

Problem: the user might want to edit item X on the list and leave its identity as X, while changing other properties. Hence, the test gives a false positive in that case. My "solution" was

index = data_list.index(item)
<edit item>
if True in [item.is_same(data_list[i]) for i in range(len(data_list)) \
               and i != index]:
   print "on list already"

That generated an error because the i in 'i != index' is not bound to the 'for i' generator. So I tested another possibility:

index = data_list.index(item)
<edit item>
if True in [item.is_same(data_list[i]) for i in\  
   range(len(data_list)).remove(index)]:
    print "on list already"

which oughta work, I think ... only it doesn't!:surprised :cry::cry::mad:

OHHH...remove() returns None and operates on the list in place. It DOES NOT return the modified list!!!! So range(9).remove() returns None, and the list is immediately garbage collected, because it can't possibly be assigned. :idea: Wait: I've got it:

M = data_list[:]
M.remove(item)
<edit item>
if True in [item.is_same(x) for x in M]:
  print "on list already"

Thanks for letting me talk out loud. :oI hope this helps someone else.

Jeff Cagle

Recommended Answers

All 2 Replies

Thanks for thinking out loud, I found it interesting!

an even better solution not requiring a slice:

if [x for x in data_list if item.is_same(x) and x is not item]:
  print "item on list already"
else:
  print "item is ok"

the generator will generate [] if no items are the same except for item itself.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.