Python Forum
strange difference between list() and tuple() using iter()
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
strange difference between list() and tuple() using iter()
#1
when using iter() then to get the items from the iterator using list() or tuple() there is a strange difference. here is the demo:
Output:
lt2a/phil /home/phil 86> py Python 3.6.9 (default, Oct 8 2020, 12:12:24) [GCC 8.4.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> a=['foo','bar','boo','far','baz'] >>> a ['foo', 'bar', 'boo', 'far', 'baz'] >>> list(x for x in a) ['foo', 'bar', 'boo', 'far', 'baz'] >>> tuple(x for x in a) ('foo', 'bar', 'boo', 'far', 'baz') >>> list(iter(x for x in a)) ['foo', 'bar', 'boo', 'far', 'baz'] >>> tuple(iter(x for x in a)) ('foo', 'bar', 'boo', 'far', 'baz') >>> b=iter(x for x in a) >>> list(b) ['foo', 'bar', 'boo', 'far', 'baz'] >>> tuple(b) () >>>
so, tuple() varies from list().

even more strange, the variance of tuple() depends on if the iterator was stored in a variable (b in this case). is there an explanation of why it differs like this or is this a bug? can someone try this in 3.7 or 3.8?
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#2
>>> a=['foo','bar','boo','far','baz']
>>> b=iter(x for x in a)
>>> type(b)
<class 'generator'>
>>> type(x for x in a)
<class 'generator'>
>>> tuple(b)
('foo', 'bar', 'boo', 'far', 'baz')
>>> list(b)
[]
x for x in a is a generator expression as well as b is generator. When you use it for first time you consume and exhaust it. That is why on second use you get empty container. You can see that if you first pass it to tuple() you get tuple, and on second use - empty list. Of course if it is not assign to a variable, you work with new generator every time, so that is "the variance" in behavior.

by the way, the use if iter() is not needed in this case (i.e. on generator expression). You can use next() on generator.
>>> next(x for x in a)
'foo'
>>> spam=(x for x in a)
>>> next(spam)
'foo'
>>> next(spam)
'bar'
>>> next(spam)
'boo'
>>> next(spam)
'far'
>>> next(spam)
'baz'
>>> next(spam)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> list(spam)
[]
at the end the generator is exhausted and you get StopIteration error.
Skaperen and ndc85430 like this post
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  What is the difference between list and tuples in Python? priya1717 1 22,286 Dec-20-2022, 11:08 AM
Last Post: ibreeden
  why tuple instead of list Skaperen 12 5,792 Feb-19-2020, 02:07 AM
Last Post: Skaperen

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020