Re: Fwd: PYTHON BUG. deleting elements of list.

2020-09-09 Thread Mats Wichmann
On 9/8/20 5:18 PM, Richard Damon wrote:
> On 9/8/20 7:06 PM, Mats Wichmann wrote:
>> On 9/7/20 5:01 PM, Driuma Nikita wrote:

>> for i, el in enumerate(_list[:]):
>>  del _list[i]
>>
> The issue isn't so much that he is modifying the list that he is
> iterating over, but also when he deletes _list[0], all the other
> elements move down,

yes, quite right, brain fail here, ignore me
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Fwd: PYTHON BUG. deleting elements of list.

2020-09-09 Thread Chris Angelico
On Wed, Sep 9, 2020 at 6:18 PM Nicholas Cole  wro
>
> On Wed, Sep 9, 2020 at 8:52 AM Chris Angelico  wrote:
>
> [snip]
> > And if you absolutely have to mutate in place:
> >
> > items[:] = [i for i in items if i not in "bcd"]
>
> How does that work to mutate in place?

Technically it constructs a new filtered list, and then replaces the
contents of the original list with the filtered one. That's
effectively an in-place mutation; any other reference to that same
list will see the change. Compare:

a = list(range(20))
b = a
a = [n for n in a if n % 3]
print(a)
print(b)

You'll see that a and b now differ. But if you use slice assignment:

a[:] = [n for n in a if n % 3]

you'll see that the two are still the same list (and "a is b" will
still be True). It's replacing the contents, rather than rebinding the
name.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Fwd: PYTHON BUG. deleting elements of list.

2020-09-09 Thread Nicholas Cole
On Wed, Sep 9, 2020 at 8:52 AM Chris Angelico  wrote:

[snip]
> And if you absolutely have to mutate in place:
>
> items[:] = [i for i in items if i not in "bcd"]

How does that work to mutate in place?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Fwd: PYTHON BUG. deleting elements of list.

2020-09-09 Thread Chris Angelico
On Wed, Sep 9, 2020 at 5:45 PM Peter Otten <__pete...@web.de> wrote:
>
> Peter Otten wrote:
>
> > If the list is huge you can also delete in reverse order:
> >
> > for i in reversed(len(_list)):
>
> Make that reversed(range(len(_list))).
>
> > if discard(_list[i]):
> > del _list[i]
>
> Example:
>
> >>> items = ['a', 'b', 'c', 'd', 'e']
> >>> for i, item in enumerate(items):
> ... if item in "bcd":
> ... del items[i]
> ...
> >>> items
> ['a', 'c', 'e']
> >>> items = ['a', 'b', 'c', 'd', 'e']
> >>> for i in reversed(range(len(items))):
> ... if items[i] in "bcd":
> ... del items[i]
> ...
> >>> items
> ['a', 'e']
>

But that's still pretty clunky AND inefficient (deleting from the
middle of a list is a slow operation). Filtering is far better.

items = [i for i in items if i not in "bcd"]

And if you absolutely have to mutate in place:

items[:] = [i for i in items if i not in "bcd"]

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Fwd: PYTHON BUG. deleting elements of list.

2020-09-09 Thread Peter Otten
Peter Otten wrote:

> If the list is huge you can also delete in reverse order:
> 
> for i in reversed(len(_list)):

Make that reversed(range(len(_list))).

> if discard(_list[i]):
> del _list[i]

Example:

>>> items = ['a', 'b', 'c', 'd', 'e']
>>> for i, item in enumerate(items):
... if item in "bcd":
... del items[i]
... 
>>> items
['a', 'c', 'e']
>>> items = ['a', 'b', 'c', 'd', 'e']
>>> for i in reversed(range(len(items))):
... if items[i] in "bcd":
... del items[i]
... 
>>> items
['a', 'e']


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


Re: Fwd: PYTHON BUG. deleting elements of list.

2020-09-08 Thread Peter Otten
Mats Wichmann wrote:

> On 9/7/20 5:01 PM, Driuma Nikita wrote:
> 
> 
>  _list = list(range(50))
>  for i, el in enumerate(_list):
>  del _list[i]
>  print(_list)
> 
> 
> Don't change the the list while you are iterating over it, it messes up
> the iteration. It's not "randomly deleting", it's when next is called to
> fetch the next item, the list has changed.
> 
> One workaround is to iterate over a copy. For example here's using
> slicing to create a new list to iterate over:
> 
> for i, el in enumerate(_list[:]):
>  del _list[i]

As Richard says, this won't work. 
Usually the best approach is to copy the items you want to keep:

_list = [item for item in _list if keep(item)]

If the list is huge you can also delete in reverse order:

for i in reversed(len(_list)):
if discard(_list[i]):
del _list[i]

(If you want to delete /all/ items use _list.clear() or del _list[:])


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


Re: Fwd: PYTHON BUG. deleting elements of list.

2020-09-08 Thread Richard Damon
On 9/8/20 7:06 PM, Mats Wichmann wrote:
> On 9/7/20 5:01 PM, Driuma Nikita wrote:
>
>
>  _list = list(range(50))
>  for i, el in enumerate(_list):
>  del _list[i]
>  print(_list)
>
>
> Don't change the the list while you are iterating over it, it messes up
> the iteration. It's not "randomly deleting", it's when next is called to
> fetch the next item, the list has changed.
>
> One workaround is to iterate over a copy. For example here's using
> slicing to create a new list to iterate over:
>
> for i, el in enumerate(_list[:]):
>  del _list[i]
>
The issue isn't so much that he is modifying the list that he is
iterating over, but also when he deletes _list[0], all the other
elements move down, so the next time when he does a del _list[1], that
will delete what started as _list[2], and with your code, when he gets
half way done he will hit an index error as he tries to delete _list[26]
from a list with only 25 elements.

-- 
Richard Damon

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


Re: Fwd: PYTHON BUG. deleting elements of list.

2020-09-08 Thread Mats Wichmann
On 9/7/20 5:01 PM, Driuma Nikita wrote:


 _list = list(range(50))
 for i, el in enumerate(_list):
 del _list[i]
 print(_list)


Don't change the the list while you are iterating over it, it messes up
the iteration. It's not "randomly deleting", it's when next is called to
fetch the next item, the list has changed.

One workaround is to iterate over a copy. For example here's using
slicing to create a new list to iterate over:

for i, el in enumerate(_list[:]):
 del _list[i]

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


Fwd: PYTHON BUG. deleting elements of list.

2020-09-08 Thread Driuma Nikita
    
    
    Пересылаемое сообщение 
   08.09.2020, 01:43, "python-list-ow...@python.org"
   :
    

   Hello! I see you want to post a message to the Python List. We would
   be happy to help, but you must subscribe first:

     [1]https://mail.python.org/mailman/listinfo/python-list

   After you have subscribed, please send your message to
   [2]python-list@python.org again. Please do not include images as this is
   a text-only forum -- instead, copy/paste or transcribe the information
   from the image that you want us to know.

   Alternatively, this list is mirrored both ways with the
   comp.lang.python newsgroup (news:comp.lang.python).

   Some people find it easier to follow this and other lists via gmane
   ([3]http://news.gmane.org/gmane.comp.python.general), a service which
   offers a newsgroup interface to many online mailing lists.

   *NB all posts to the mailing list are publicly archived at:*

     [4]https://mail.python.org/pipermail/python-list

    

    
    Конец пересылаемого сообщения 
    
    
   With Regards.
   Python is best.
    

References

   Visible links
   1. https://mail.python.org/mailman/listinfo/python-list
   2. mailto:python-list@python.org
   3. http://news.gmane.org/gmane.comp.python.general
   4. https://mail.python.org/pipermail/python-list
--- Begin Message ---
   Hello, python creators and bug fixers.
   I have same strange Basic-type problem time after time.
   Deleting elements of lists - is Basic of basics thing. And i can't count
   on it. It doesn't work in some cases.
   I found a simple example, and example of my problem - to modify the string
   data that i got from parsing internet, web-data - this is the case i got
   the problem.
    
   Simple Example 1.
   I expect to delete all/any elements by index from list by using del,
   .remove(), pop() - it must work as usually. But that doesn't happens.

 _list = list(range(50))
 for i, el in enumerate(_list):
     del _list[i]
 print(_list)

   result:

 # [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35,
 37, 39, 41, 43, 45, 47, 49]

   Same for pop(i) and remove(el).
    
   Works only filter(), creating new _list2 with .append()
   , with SAME IF-statements - as for delete.(thats for Example 2 and problem
   i met with)
    
   Example 2.
   I got a string from parsing something from internet. This is a body of one
   message from my Gmail this time.
   And there is no any way to delete empty elements in existing list to
   pretty the final output-data.
   Sometimes it deletes random elements, but not all. Sometimes deletes
   nothing.
   Another diagnose - tried to take len() of of each element, and it says 0
   to non zero elements.
   The only solution is to create a new list and append needed items instead
   of delete non-needed in first-list.
    
   There are many EMPTY elements. I do .split("'r\n") and trying to run a
   FOR-cycle.
   The list example:
   ['Вы вошли в аккаунт Google с нового Xiaomi HM Note 2', '', '', '', 'Для
   завершения настройки установите официальные приложения от Google.', '',
   '', 'Google Sheets', '', 'Google Sheets', '', 'Создавайте таблицы и
   работайте над ними вместе', '', '4.5/5 Stars', '', '', '', '', '',
   'СКАЧАТЬ', '', '', '', '', '', '', '', 'Google Calendar', '', 'Google
   Calendar', '', 'Все ваши календари, мероприятия и встречи в одном
   приложении', '', '', '', '', '', '', '', 'СКАЧАТЬ', '', '', '', '', '',
   '', '', 'Google Duo', '', 'Google Duo', '', 'Проводите видеовстречи с
   высоким качеством изображения', '', '4.5/5 Stars', '', '', '', '', '',
   'СКАЧАТЬ', '', '', '', '', '', '', '', 'Не отвечайте на это письмо. Вы
   получили это сообщение, так как недавно  ', 'активировали свой аккаунт
   Google на Xiaomi HM Note 2.', '', '', '', '© 2018 Google LLC 1600
   Amphitheatre Parkway, Mountain View, CA 94043, USA', '', '', '', '',
   '—', '', '', '', '']
   With Regards.
--- End Message ---
-- 
https://mail.python.org/mailman/listinfo/python-list