* Alex Martelli wrote, On 3/29/07 9:46 AM: > <[EMAIL PROTECTED]> wrote: >> another query, in the docs, list(a) and a[:] does the same thing (a = >> [1,2,3] for example), but besides the speed of slicing is faster than >> list(), what advantage is there for using list(a) in this case ? > > Readability (a word is more readable than idiomatic punctuation), and > conceptual uniformity with making shallow copies of other containers of > known types such as sets and dicts.
I just want to summarizes what Alex is saying (correct me if I'm wrong!): usually, you do not want to use copy.copy, and copy.deepcopy only when you really need it (which is, if I search for it in my library, very seldom). As to whether use list(lst), [x for x in lst], list(x for x in lst), or just lst[:], I'd summarize it to this: list(lst): most expressive; use if you want to explicitly create a copy of a list and only a list or if you want to ensure that whatever sequence you received gets transformed to a list. [list comprehension] and gen(erators): usually to create a copy of a list, generator function or sequence with some modification; using list comprehension always creates list, with a generator setup you could do (for example): tup = tuple(x + 1 for x in int_lst) Some people also argue generators are faster, but I'd advise you to use what is more understandable first - you are asking what methods are faster, but keep in mind: "premature [code] optimization is the root of all evil", or so... (from T. Hoare/D. Knuth). And believe me, this statement holds always, as I had to learn the bloody hard way! using slices[:]: preserves the sequence you are using, so you could create a function that accepts list, tuples, strings or any other sequence as input and makes a copy of the sequence regardless of its type and returns that type. A very nice example of this is can be found in the Permutations/Combinations/Selections recipe from the Python Cookbook (R 19.15): def _combinators(_handle, items, n): # factored-out common structure for: # combinations, selections and permutations if n == 0: yield items[:0] return for i in range(len(items)): this_one = items[i:i + 1] for cc in _combinators(_handle, _handle(items, i), n - 1): yield this_one + cc def combinations(items, n): """ take n distinct items, order matters """ def skipIthItem(items, i): return items[:i] + items[i+1:] return _combinators(skipIthItem, items, n) def uniqueCombinations(items, n): """ take n distinct items, order is irrelevant """ def afterIthItem(items, i): return items[i+1:] return _combinators(afterIthItem, items, n) def selections(items, n): """ take n (not necessarily distinct) items, order matters """ def keepAllItems(items, i): return items return _combinators(keepAllItems, items, n) def permutations(items): """ take all items, order matters """ return combinations(items, len(items)) Because _combinators() returns "yield items[:0]" (i.e. the empty input sequence) instead of, say, an empty list ("yield list()"), and because the assignment to this_one in _combinators() is not "this_one = [items[i]]", but "this_one = items[i:i+1]", you can use any sequence as input to these functions, not just lists. Yet, it arguably might not be the most efficient solution because of the recurring sequence concatenations in the inner functions and the yield statement... -Florian -- http://mail.python.org/mailman/listinfo/python-list