Re: [Tutor] flattening a list
Jacob S. wrote: Ahh, my pitiful form of flattening a list that cheats... def flatten(li): li = str(li) li = li.replace("[","") li = li.replace("]","") li = li.replace("(","") li = li.replace(")","") li = "[%s]"%li return eval(li) It works! It's probably just a bit slower. Jacob Schmidt ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor Actually, this doesn't even work 100% of the time. If you have a list as the key or value in a dictionary, it will remove the brackets, at which point eval will fail since the dictionary will look like {7:8,9,10} (assuming an original dictionary of {7:[8,9,10]}), which results in a SyntaxError -- Email: singingxduck AT gmail DOT com AIM: singingxduck Programming Python for the fun of it. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] flattening a list
Ahh, my pitiful form of flattening a list that cheats... def flatten(li): li = str(li) li = li.replace("[","") li = li.replace("]","") li = li.replace("(","") li = li.replace(")","") li = "[%s]"%li return eval(li) It works! It's probably just a bit slower. Jacob Schmidt ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] flattening a list
One final note to wrap things up. I posted a slightly cleaner version of my code on the Python Cookbook, with a reference to the solutions of Gonçalo and Danny via the tutor archives here: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/363051 -- Email: singingxduck AT gmail DOT com AIM: singingxduck Programming Python for the fun of it. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] flattening a list
You should post this on the Python Cookbook http://aspn.activestate.com/ASPN/Python/Cookbook/ Orri Ganel wrote > Bill Kranec wrote: > > > >> Hello, > > >> > >> I have a list of lists, for example [ [1,2] , [3,4] ], and I would > > >> like to pass all the elements of that list as arguments to a function > > >> (for example the intersection of all list elements). Is there a > > >> command in regular Python to do this? I would like to avoid the > > >> hassle and speed hit of a loop to extract all the list elements. > > >> > >> In the past, I believe I have used something like flatten(list), which > > >> was part of Numarray (I think). Am I missing an obvious or clever > > >> solution in regular Python? > > >> > >> Thanks for your help! > > >> > >> Bill > > >> ___ > > >> Tutor maillist - Tutor@python.org > > >> http://mail.python.org/mailman/listinfo/tutor > > >> > > Well, here's something i put together (works for lists and tuples, > ignores strings and dicts): > > > > ### Start Code ### > > def flatten(sequence): > > > >def rflat(seq2): > >seq = [] > >for entry in seq2: > >if '__contains__' in dir(entry) and \ > > type(entry) != str and \ > > type(entry)!=dict: > >seq.extend([i for i in entry]) > >else: > >seq.append(entry) > >return seq > > > >def seqin(sequence): > >for i in sequence: > >if '__contains__' in dir(i) and \ > > type(i) != str and \ > > type(i) != dict: > >return True > >return False > > > >seq = sequence[:] > >while seqin(seq): > >seq = rflat(seq) > >return seq > > ### End Code ### > > > > Tested it on a few different scenarios, all performed as expected: > > > > >>> flatten([1]) > > [1] > > >>> flatten([1,[1]]) > > [1, 1] > > >>> flatten(['ab',1]) > > ['ab', 1] > > >>> flatten([10,(34,42),54,'abc']) > > [10, 34, 42, 54, 'abc'] > > >>> flatten([{'abc':[1,2,3]},[{'a':'1'},{'[1,2]':'ab'}]]) > > [{'abc': [1, 2, 3]}, {'a': '1'}, {'[1,2]': 'ab'}] > > > > Cheers, > > Orri > __ Do you Yahoo!? The all-new My Yahoo! - Get yours free! http://my.yahoo.com ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] flattening a list
Chad Crabtree wrote: The only problem with this if it is to big or to deeply nested then it will overflow the stack? Danny Yoo has given a mind-blowing continuation implementation that will not overflow the stack. Below goes a recursive-iterator implementation. To avoid deep recursion the code can simluate its own stack (or hope that Python gains tail-call optimization *grin*) but for simplicity's sake we just use recursion. def isIterable(iterable): """Test for iterable-ness.""" try: iter(iterable) except TypeError: return False return True def isBadIterable(iterable): """Return True if it's a 'bad' iterable. Note: string's are bad because, when iterated they return strings making itterflatten loop infinitely. """ return isinstance(iterable, basestring) def iterflatten(iterable): """Return a flattened iterator.""" it = iter(iterable) for e in it: if isIterable(e) and not isBadIterable(e): #Recurse into iterators. for f in iterflatten(e): yield f else: yield e A test: for elem in iterflatten([1, 2, [3, 4, (5, 6), 7], 8, [9], [10, 11, iter([12, 13])]]): print elem And it gives: >>> 1 2 3 4 5 6 7 8 9 10 11 12 13 Best regards, G. Rodrigues ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] flattening a list
> > def flatten(a): > >if not isinstance(a,(tuple,list)): return [a] > >if len(a)==0: return [] > >return flatten(a[0])+flatten(a[1:]) > The only problem with this if it is to big or to deeply nested then it > will overflow the stack? Yes, it can overflow in its current incarnation. There is a way to fix that. [WARNING WARNING: The code presented below is very evil, but I just can't resist. *grin* Please do not try to understand the code below, as it is not meant to be read by humans. If you are just learning Python, please skip this message.] There's a way to systematically transform it so that it doesn't overflow, by using "trampolining-style" programming. This technique turns any recursive function into one that only consumes a constant amount of stack space. It's used by programming language theory folks, despite being utterly weird. *grin* I think I wrote a brief introduction to the topic on Python-Tutor list, and have also applied it in a small project (PyScheme). For your (or my?) amusement, here's the transformed flatten() function in trampolined style: ### def flatten(a): """Flatten a list.""" return bounce(flatten_k(a, lambda x: x)) def bounce(thing): """Bounce the 'thing' until it stops being a callable.""" while callable(thing): thing = thing() return thing def flatten_k(a, k): """CPS/trampolined version of the flatten function. The original function, before the CPS transform, looked like this: def flatten(a): if not isinstance(a,(tuple,list)): return [a] if len(a)==0: return [] return flatten(a[0])+flatten(a[1:]) The following code is not meant for human consumption. """ if not isinstance(a,(tuple,list)): return lambda: k([a]) if len(a)==0: return lambda: k([]) def k1(v1): def k2(v2): return lambda: k(v1 + v2) return lambda: flatten_k(a[1:], k2) return lambda: flatten_k(a[0], k1) ### This actually does something useful. ### >>> flatten([1, [2, [3, 4]]]) [1, 2, 3, 4] ### Best of all, it does not stack-overflow. We can test this on an evil constructed example: ### >>> def makeEvilList(n): ... result = [] ... for i in xrange(n): ... result = [[result], i] ... return result ... >>> evilNestedList = makeEvilList(sys.getrecursionlimit()) >>> assert range(sys.getrecursionlimit()) == flatten(evilNestedList) >>> ### And it does work. That being said, "trampolined-style" is just evil in Python: I would not want to inflict that code on anyone, save in jest. *grin* ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] flattening a list
The only problem with this if it is to big or to deeply nested then it will overflow the stack? Mario Rol wrote: > nice and concise, found on comp.lang.python: > > def flatten(a): >if not isinstance(a,(tuple,list)): return [a] >if len(a)==0: return [] >return flatten(a[0])+flatten(a[1:]) > > _ > Play online games with your friends with MSN Messenger > http://messenger.msn.nl/ > > ___ > Tutor maillist - Tutor@python.org > http://mail.python.org/mailman/listinfo/tutor > > __ Do you Yahoo!? Yahoo! Mail - 250MB free storage. Do more. Manage less. http://info.mail.yahoo.com/mail_250 ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] flattening a list
nice and concise, found on comp.lang.python: def flatten(a): if not isinstance(a,(tuple,list)): return [a] if len(a)==0: return [] return flatten(a[0])+flatten(a[1:]) _ Play online games with your friends with MSN Messenger http://messenger.msn.nl/ ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] flattening a list
Bill Kranec wrote: Hello, I have a list of lists, for example [ [1,2] , [3,4] ], and I would like to pass all the elements of that list as arguments to a function (for example the intersection of all list elements). Is there a command in regular Python to do this? I would like to avoid the hassle and speed hit of a loop to extract all the list elements. In the past, I believe I have used something like flatten(list), which was part of Numarray (I think). Am I missing an obvious or clever solution in regular Python? Thanks for your help! Bill ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor Well, here's something i put together (works for lists and tuples, ignores strings and dicts): ### Start Code ### def flatten(sequence): def rflat(seq2): seq = [] for entry in seq2: if '__contains__' in dir(entry) and \ type(entry) != str and \ type(entry)!=dict: seq.extend([i for i in entry]) else: seq.append(entry) return seq def seqin(sequence): for i in sequence: if '__contains__' in dir(i) and \ type(i) != str and \ type(i) != dict: return True return False seq = sequence[:] while seqin(seq): seq = rflat(seq) return seq ### End Code ### Tested it on a few different scenarios, all performed as expected: >>> flatten([1]) [1] >>> flatten([1,[1]]) [1, 1] >>> flatten(['ab',1]) ['ab', 1] >>> flatten([10,(34,42),54,'abc']) [10, 34, 42, 54, 'abc'] >>> flatten([{'abc':[1,2,3]},[{'a':'1'},{'[1,2]':'ab'}]]) [{'abc': [1, 2, 3]}, {'a': '1'}, {'[1,2]': 'ab'}] Cheers, Orri -- Email: singingxduck AT gmail DOT com AIM: singingxduck Programming Python for the fun of it. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] flattening a list
On Wed, 12 Jan 2005 [EMAIL PROTECTED] wrote: > Quoting Bill Kranec <[EMAIL PROTECTED]>: > > > I have a list of lists, for example [ [1,2] , [3,4] ], and I would like > > to pass all the elements of that list as arguments to a function (for > > example the intersection of all list elements). Is there a command in > > regular Python to do this? I would like to avoid the hassle and speed > > hit of a loop to extract all the list elements. > > I don't think so... > > There is a recipe on activestate for a flatten function. > > Or you could use a list comprehension: > > >>> arr = zip(range(10), range(10, 20)) > >>> arr > [(0, 10), (1, 11), (2, 12), (3, 13), (4, 14), (5, 15), (6, 16), (7, 17), (8, > 18), (9, 19)] > >>> [x for y in arr for x in y] > [0, 10, 1, 11, 2, 12, 3, 13, 4, 14, 5, 15, 6, 16, 7, 17, 8, 18, 9, 19] > Nice. And there's: >>> arr = zip(range(10), range(10, 20)) >>> arr [(0, 10), (1, 11), (2, 12), (3, 13), (4, 14), (5, 15), (6, 16), (7, 17), (8, 18), (9, 19)] >>> reduce(lambda x,y:x+y, arr) (0, 10, 1, 11, 2, 12, 3, 13, 4, 14, 5, 15, 6, 16, 7, 17, 8, 18, 9, 19) >>> > -- ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] flattening a list
Quoting Bill Kranec <[EMAIL PROTECTED]>: > I have a list of lists, for example [ [1,2] , [3,4] ], and I would like > to pass all the elements of that list as arguments to a function (for > example the intersection of all list elements). Is there a command in > regular Python to do this? I would like to avoid the hassle and speed > hit of a loop to extract all the list elements. I don't think so... There is a recipe on activestate for a flatten function. Or you could use a list comprehension: >>> arr = zip(range(10), range(10, 20)) >>> arr [(0, 10), (1, 11), (2, 12), (3, 13), (4, 14), (5, 15), (6, 16), (7, 17), (8, 18), (9, 19)] >>> [x for y in arr for x in y] [0, 10, 1, 11, 2, 12, 3, 13, 4, 14, 5, 15, 6, 16, 7, 17, 8, 18, 9, 19] -- John. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] flattening a list
Hello, I have a list of lists, for example [ [1,2] , [3,4] ], and I would like to pass all the elements of that list as arguments to a function (for example the intersection of all list elements). Is there a command in regular Python to do this? I would like to avoid the hassle and speed hit of a loop to extract all the list elements. In the past, I believe I have used something like flatten(list), which was part of Numarray (I think). Am I missing an obvious or clever solution in regular Python? Thanks for your help! Bill ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor