[Python-3000] Iterables and scalars was: sets in P3K?

Raymond Hettinger rhettinger at ewtllc.com
Wed Apr 26 20:07:39 CEST 2006


Edward Loper wrote:

>I think that a significant motivation for people that propose set 
>literals is that the following is just plain ugly:
>
>    s = set([1,2,3])
>
>It seems much more natural to write:
>
>    s = set(1, 2, 3)
>
>However, it is fairly common to want to build a set from a collection, 
>an iterator, or a genexp.  With the current notation, all three of these 
>are easy.  But with this "more natural" notation, they're no longer 
>possible without resorting to varargs (which would create an unnecessary 
>imtermediary tuple).  I.e., we don't want to lose the ability to do any 
>of the following:
>
>   s = set(my_list)
>   s = set(enumerate(my_list))
>   s = set(x for x in collection if x>10)
>
>One way around this conflict might be to define a new factory function, 
>that generates a set from an iterable.  I.e., something like:
>
>   s = set.from_iter(my_list)
>   s = set.from_iter(enumerate(my_list))
>   s = set.from_iter(x for x in collection if x>10)
>  
>
We're no longer talking about an issue unique to the set and frozenset 
datatypes.  Many elements of the language are challenged by conflicting 
desires for a function or type choose between taking an iterable 
argument or to have them already unwound.

IMO, the worst solution is trying to accommodate both within a single 
callable.  The problematic %-formatting operator is one example.  The 
min() and max() functions are another:

    >>> min(3,4,5)
    3
    >>> min([3,4,5])
    3

The current solution for sets is to provide only the iterable form and 
to require the user to create a list when he/she wants to write-out a 
literal:  set([1,2,3]).  The advantage of this approach is that it has a 
small footprint in terms of human memory because it takes advantage of 
pre-existing knowledge about how to write list literals and because it 
doesn't double the number of forms for every function and type.

Edward's solution is to provide an alternate classmethod or factory 
function.  IMO, this doesn't solve the general problem unless it is 
applied throughout the language:  

   list(1)
   list.from_iter([1])
   tuple(1)
   tuple.from_iter([1])
   set(1)
   set.from_iter([1])

If those examples make your stomach churn, then let's not go down the 
path of adding all these classmethods and factory functions.  The 
existing approach using list literals is dirt simple and universally 
applicable.  While writing set([1,2,3]) is not a perfect solution, it is 
much less complex than non-generalizable alternatives involving 
classmethods, factory functions, or punctuation.


Raymond




More information about the Python-3000 mailing list