Issue41518
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2020-08-10 18:56 by rameshsahoo11, last changed 2022-04-11 14:59 by admin. This issue is now closed.
Messages (9) | |||
---|---|---|---|
msg375136 - (view) | Author: Ramesh Sahoo (rameshsahoo11) | Date: 2020-08-10 18:56 | |
With for loop, I am able to print all elements in the list 'a' a = ['a','a','b','b','c'] for i in a: print(i) O/P: a a b b c but with the following loop, python only prints 3 uniq elements instead of 5. stack = ['(', '(', '[', ']', ')'] for i in stack: print(i) O/P: ( ] ) Is this is intended behavior? |
|||
msg375142 - (view) | Author: Eric V. Smith (eric.smith) * | Date: 2020-08-10 19:08 | |
Here's what I see: Python 3.6.9 (default, Jul 21 2019, 14:33:59) [GCC 7.4.0] on cygwin Type "help", "copyright", "credits" or "license" for more information. >>> stack = ['(', '(', '[', ']', ')'] >>> for i in stack: ... print(i) ... ( ( [ ] ) That looks correct to me. What exact version of 3.6 are you using, and on what platform? |
|||
msg375148 - (view) | Author: Eric V. Smith (eric.smith) * | Date: 2020-08-10 19:59 | |
Also, how are you running this? From the interactive shell (like I show in my previous message), or some other way? |
|||
msg375156 - (view) | Author: Steven D'Aprano (steven.daprano) * | Date: 2020-08-10 23:18 | |
Python 3.6 has reached security-fix only stage: https://www.python.org/dev/peps/pep-0494/#schedule-last-bugfix-release so even if this is a bug, it won't be fixed in 3.6. I cannot reproduce this in 3.7, and Eric cannot reproduce in 3.6.9, so I'm closing the issue. Please re-open if you can reproduce in 3.8 or better. (3.7 is also only accepting security fixes only.) (Eric do you concur? If you disagree please feel free to re-open.) |
|||
msg375158 - (view) | Author: Eric V. Smith (eric.smith) * | Date: 2020-08-11 00:02 | |
I agree, Steven. This doesn't seem to be a problem with Python. It's more likely a problem with the user's shell, or some other environment integration problem. If it can be duplicated in 3.8 or later, we can investigate further. |
|||
msg375164 - (view) | Author: Ramesh Sahoo (rameshsahoo11) | Date: 2020-08-11 07:16 | |
Hi all, Thanks for your valuable response. I would like to inform you that I found this issue while playing with the following code. This is reproducible with Python 3.8. Please find the following details and let me know if I am doing something wrong. [Using for loop popping elements] import sys stack,braces = [],{'(':')','{':'}','[':']'} stack = [s for s in "(([])"] c = 0 print(f"Python version: {sys.version}") print(f"Before for loop:\nbraces.keys = {braces.keys()}\nbraces.items = {braces.items()}\nstack = {stack}\n\n") for i in stack: c += 1 print(f"{'='*10} loop {c} {'='*10}") print("just after for loop stack =",stack) print(f"Just after for loop i =",i) print(f"Just after for loop: Is i'{i}' found in braces.keys:{i in braces.keys()}") if i in braces.keys(): print(f"inside if i = {i}") print("inside if stack =",stack) print("inside if Popped =",stack.pop(stack.index(i))) print(f"inside if after popped stack = {stack}\n") continue else: print(f"in else: Is i'{i}' found in braces.keys:{i in braces.keys()}") print(f"in else stack = {stack}\n") [Program Output] $ python3 test1.py Python version: 3.8.0 (default, Nov 14 2019, 22:29:45) [GCC 5.4.0 20160609] Before for loop: braces.keys = dict_keys(['(', '{', '[']) braces.items = dict_items([('(', ')'), ('{', '}'), ('[', ']')]) stack = ['(', '(', '[', ']', ')'] ========== loop 1 ========== just after for loop stack = ['(', '(', '[', ']', ')'] Just after for loop i = ( Just after for loop: Is i'(' found in braces.keys:True inside if i = ( inside if stack = ['(', '(', '[', ']', ')'] inside if Popped = ( inside if after popped stack = ['(', '[', ']', ')'] ========== loop 2 ========== just after for loop stack = ['(', '[', ']', ')'] Just after for loop i = [ Just after for loop: Is i'[' found in braces.keys:True inside if i = [ inside if stack = ['(', '[', ']', ')'] inside if Popped = [ inside if after popped stack = ['(', ']', ')'] ========== loop 3 ========== just after for loop stack = ['(', ']', ')'] Just after for loop i = ) Just after for loop: Is i')' found in braces.keys:False in else: Is i')' found in braces.keys:False in else stack = ['(', ']', ')'] [Summary] stack = ['(', '(', '[', ']', ')'] => [loop 1] is correct where the right element "(" has been popped. ['(', '[', ']', ')'] => [loop 2] "(" element should have been popped but "[" chosen to be popped. This seems to be incorrect. => There must be 5 iterations(3 in if block and 2 in else block) but loop completed with 3 iterations(2 in if and one in else). I am not sure if I am doing something wrong or it is a buggy behavior. [Popping elements manually gives correct behavior] import sys print(f"Python Version: {sys.version}") stack,braces = [],{'(':')','{':'}','[':']'} stack = [s for s in "(([])"] print(f"Original:\nbraces.keys = {braces.keys()}\nbraces.items = {braces.items()}\nstack = {stack}\n\n") # Popping '(' print(f"Popped {stack.pop(stack.index('('))}") print(f"stack after popping '(' = {stack}") # Popping '(' print(f"Popped {stack.pop(stack.index('('))}") print(f"stack after popping '(' = {stack}") # Popping '[' print(f"Popped {stack.pop(stack.index('['))}") print(f"stack after popping '[' = {stack}") [Program Output] Python Version: 3.8.0 (default, Nov 14 2019, 22:29:45) [GCC 5.4.0 20160609] Original: braces.keys = dict_keys(['(', '{', '[']) braces.items = dict_items([('(', ')'), ('{', '}'), ('[', ']')]) stack = ['(', '(', '[', ']', ')'] Popped ( stack after popping '(' = ['(', '[', ']', ')'] Popped ( stack after popping '(' = ['[', ']', ')'] Popped [ stack after popping '[' = [']', ')'] |
|||
msg375165 - (view) | Author: Ramesh Sahoo (rameshsahoo11) | Date: 2020-08-11 07:34 | |
Additional note: The following program completes all 5 iterations. #!/usr/bin/python3 stack = [s for s in range(5)] c = 0 for i in stack: c += 1 print(f"{'='*10} loop {c} {'='*10}") if i == 0 or i == 1 or i == 2: print(f"{i}\n") else: print(f"{i}\n") $ python3 test1.py ========== loop 1 ========== 0 ========== loop 2 ========== 1 ========== loop 3 ========== 2 ========== loop 4 ========== 3 ========== loop 5 ========== 4 |
|||
msg375168 - (view) | Author: Steven D'Aprano (steven.daprano) * | Date: 2020-08-11 09:59 | |
On Tue, Aug 11, 2020 at 07:16:20AM +0000, Ramesh Sahoo wrote: > for i in stack: > print("inside if Popped =",stack.pop(stack.index(i))) You are mutating the list while you iterate over it. This is prone to cause trouble. Here's is a much smaller and simpler demonstration: items = [1, 2, 3, 4, 5] for index, value in enumerate(items): print(f"index: {index}, value: {value}, items: {items}") if value == 2: x = items.pop(index) print(f"after popping 2: {items}") which has output: index: 0, value: 1, items: [1, 2, 3, 4, 5] index: 1, value: 2, items: [1, 2, 3, 4, 5] after popping 2: [1, 3, 4, 5] index: 2, value: 4, items: [1, 3, 4, 5] index: 3, value: 5, items: [1, 3, 4, 5] If you trace the code execution in your head, you will see that this is correct behaviour: Python is walking the list from position to position, but you removed one of the values so everything shifts and you end up skipping a value, because it moves before the loop can reach it. The lesson here is: Don't mutate a list that you are iterating over if you can avoid it. It you cannot avoid it, you can avoid problems by iterating in reverse, and only mutating the part of the list you have already processed. But better to avoid mutation altogether. So not a bug. Python is doing exactly what you told it to do. |
|||
msg375194 - (view) | Author: Ramesh Sahoo (rameshsahoo11) | Date: 2020-08-11 19:10 | |
Thank Steven for correcting and guiding me. |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:59:34 | admin | set | github: 85690 |
2020-08-11 19:17:20 | Jeffrey.Kintscher | set | nosy:
- Jeffrey.Kintscher |
2020-08-11 19:10:27 | rameshsahoo11 | set | messages: + msg375194 |
2020-08-11 10:02:14 | eric.smith | set | status: open -> closed resolution: not a bug |
2020-08-11 09:59:52 | steven.daprano | set | messages: + msg375168 |
2020-08-11 07:34:14 | rameshsahoo11 | set | messages: + msg375165 |
2020-08-11 07:16:35 | rameshsahoo11 | set | resolution: works for me -> (no value) |
2020-08-11 07:16:20 | rameshsahoo11 | set | status: closed -> open messages: + msg375164 versions: + Python 3.8, - Python 3.6 |
2020-08-11 00:02:19 | eric.smith | set | messages: + msg375158 |
2020-08-10 23:18:35 | steven.daprano | set | status: open -> closed nosy: + steven.daprano messages: + msg375156 resolution: works for me stage: resolved |
2020-08-10 22:44:05 | Jeffrey.Kintscher | set | nosy:
+ Jeffrey.Kintscher |
2020-08-10 19:59:33 | eric.smith | set | messages: + msg375148 |
2020-08-10 19:08:20 | eric.smith | set | nosy:
+ eric.smith messages: + msg375142 |
2020-08-10 18:56:50 | rameshsahoo11 | create |