Re: [Tutor] flattening a list

2005-01-22 Thread Orri Ganel
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

2005-01-22 Thread Jacob S.
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

2005-01-14 Thread Orri Ganel
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

2005-01-13 Thread Chad Crabtree
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

2005-01-13 Thread Gonçalo Rodrigues
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

2005-01-12 Thread Danny Yoo

> > 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

2005-01-12 Thread Chad Crabtree
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

2005-01-12 Thread Mario Rol
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

2005-01-12 Thread Orri Ganel
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

2005-01-11 Thread Marilyn Davis
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

2005-01-11 Thread jfouhy
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

2005-01-11 Thread Bill Kranec
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