431,827 Members | 2,155 Online + Ask a Question
Need help? Post your question and get tips & solutions from a community of 431,827 IT Pros & Developers. It's quick & easy.

# Flatten a list/tuple and Call a function with tuples

 P: n/a Hi, I am wondering how do I 'flatten' a list or a tuple? For example, I'd like to transform[1, 2, (3,4)] or [1,2,[3,4]] to [1,2,3,4]. Another question is how do I pass a tuple or list of all the aurgements of a function to the function. For example, I have all the arguments of a function in a tuple a=(1,2,3). Then I want to pass each item in the tuple to a function f so that I make a function call f(1,2,3). In perl it is a given, but in python, I haven't figured out a way to do it. (Maybe apply? but it is deprecated?) Thanks, cg Jul 25 '07 #1
25 Replies

 P: n/a On Jul 25, 9:50 am, beginner f(a) def f (tuple): x,y,z = tuple You could also pass the elements of the tuple in: f(a, a, a) That would do it the way you describe in your post. Mike Jul 25 '07 #2

 P: n/a On Wed, 25 Jul 2007 14:50:18 +0000, beginner wrote: Hi, I am wondering how do I 'flatten' a list or a tuple? For example, I'd like to transform[1, 2, (3,4)] or [1,2,[3,4]] to [1,2,3,4]. A recursive function, always yielding the first element of the list, could do the job. See the ASPN Python Cookbook for a few implementations. http://aspn.activestate.com/ASPN/search? query=flatten§ion=PYTHONCKBK&type=Subsection Another question is how do I pass a tuple or list of all the aurgements of a function to the function. For example, I have all the arguments of a function in a tuple a=(1,2,3). Then I want to pass each item in the tuple to a function f so that I make a function call f(1,2,3). In perl it is a given, but in python, I haven't figured out a way to do it. (Maybe apply? but it is deprecated?) >>def foo(a, b, c): print a, b, c .... >>t = (1, 2, 3)foo(*t) 1 2 3 Have a look at the official tutorial, 4.7.4 http://www.python.org/doc/ current/tut/node6.html#SECTION006740000000000000000 Thanks, cg HTH, Stargaming Jul 25 '07 #3

 P: n/a On Jul 25, 10:19 am, Stargaming def foo(a, b, c): print a, b, c ... >t = (1, 2, 3)foo(*t) 1 2 3 Have a look at the official tutorial, 4.7.4http://www.python.org/doc/ current/tut/node6.html#SECTION006740000000000000000 Thanks, cg HTH, Stargaming Hi Stargaming, I know the * operator. However, a 'partial unpack' does not seem to work. def g(): return (1,2) def f(a,b,c): return a+b+c f(*g(),10) will return an error. Do you know how to get that to work? Thanks, cg Jul 25 '07 #4

 P: n/a On Jul 25, 10:46 am, beginner >def foo(a, b, c): print a, b, c ... >>t = (1, 2, 3) >>foo(*t) 1 2 3 Have a look at the official tutorial, 4.7.4http://www.python.org/doc/ current/tut/node6.html#SECTION006740000000000000000 Thanks, cg HTH, Stargaming Hi Stargaming, I know the * operator. However, a 'partial unpack' does not seem to work. def g(): return (1,2) def f(a,b,c): return a+b+c f(*g(),10) will return an error. Do you know how to get that to work? Thanks, cg As I mentioned, you can access the elements individually using square brackets. The following works: f(g(), g(), 10) But it's not clear. Unfortunately, I'm not seeing much else for tuple unpacking except the obvious: a,b=g() f(a,b,10) Mike Jul 25 '07 #5

 P: n/a On Jul 25, 11:00 am, kyoso...@gmail.com wrote: On Jul 25, 10:46 am, beginner def foo(a, b, c): print a, b, c ... >t = (1, 2, 3) >foo(*t) 1 2 3 Have a look at the official tutorial, 4.7.4http://www.python.org/doc/ current/tut/node6.html#SECTION006740000000000000000 Thanks, cg HTH, Stargaming Hi Stargaming, I know the * operator. However, a 'partial unpack' does not seem to work. def g(): return (1,2) def f(a,b,c): return a+b+c f(*g(),10) will return an error. Do you know how to get that to work? Thanks, cg As I mentioned, you can access the elements individually using square brackets. The following works: f(g(), g(), 10) But it's not clear. Unfortunately, I'm not seeing much else for tuple unpacking except the obvious: a,b=g() f(a,b,10) Mike- Hide quoted text - - Show quoted text - Unfortunately f(g(), g(), 10) is calling g() twice. Sometimes this is not a good idea. a,b=g() f(a,b,10) would work until you want it to be an expression. Jul 25 '07 #6

 P: n/a beginner wrote: On Jul 25, 10:19 am, Stargaming On Wed, 25 Jul 2007 14:50:18 +0000, beginner wrote: Hi, I am wondering how do I 'flatten' a list or a tuple? For example, I'd like to transform[1, 2, (3,4)] or [1,2,[3,4]] to [1,2,3,4]. A recursive function, always yielding the first element of the list,could do the job. See the ASPN Python Cookbook for a fewimplementations.http://aspn.activestate.com/ASPN/search?query=flatten§ion=PYTHONCKBK&type=Subsectio n Another question is how do I pass a tuple or list of all the aurgements of a function to the function. For example, I have all the arguments of a function in a tuple a=(1,2,3). Then I want to pass each item in the tuple to a function f so that I make a function call f(1,2,3). In perl it is a given, but in python, I haven't figured out a way to do it. (Maybe apply? but it is deprecated?)def foo(a, b, c): print a, b, c ... >>t = (1, 2, 3)foo(*t) 1 2 3Have a look at the official tutorial, 4.7.4http://www.python.org/doc/current/tut/node6.html#SECTION006740000000000000000 Thanks, cg HTH,Stargaming Hi Stargaming, I know the * operator. However, a 'partial unpack' does not seem to work. def g(): return (1,2) def f(a,b,c): return a+b+c f(*g(),10) will return an error. Do you know how to get that to work? f(*(g() + (10,)) Not the most beautiful solution, but it works. Diez Jul 25 '07 #7

 P: n/a beginner

 P: n/a beginner wrote: On Jul 25, 10:19 am, Stargaming On Wed, 25 Jul 2007 14:50:18 +0000, beginner wrote: >>Hi,I am wondering how do I 'flatten' a list or a tuple? For example, I'dlike to transform[1, 2, (3,4)] or [1,2,[3,4]] to [1,2,3,4]. A recursive function, always yielding the first element of the list,could do the job. See the ASPN Python Cookbook for a few implementations.http://aspn.activestate.com/ASPN/search?query=flatten§ion=PYTHONCKBK&type=Subsectio n >>Another question is how do I pass a tuple or list of all the aurgementsof a function to the function. For example, I have all the arguments ofa function in a tuple a=(1,2,3). Then I want to pass each item in thetuple to a function f so that I make a function call f(1,2,3). In perlit is a given, but in python, I haven't figured out a way to do it.(Maybe apply? but it is deprecated?)def foo(a, b, c): print a, b, c ... >>>>t = (1, 2, 3)foo(*t) 1 2 3Have a look at the official tutorial, 4.7.4http://www.python.org/doc/current/tut/node6.html#SECTION006740000000000000000 >>Thanks,cg HTH,Stargaming Hi Stargaming, I know the * operator. However, a 'partial unpack' does not seem to work. def g(): return (1,2) def f(a,b,c): return a+b+c f(*g(),10) will return an error. Do you know how to get that to work? Thanks, cg Were this not hypothetical, I would make use of the commutative property of addition: f(10, *g()) Proof: 1+2+10 = 10+1+2 Also, this has not been suggested: pydef g(): .... return (1,2) .... pydef f(a,b,c): .... return a+b+c .... pyf(c=10, *g()) 13 James Jul 25 '07 #9

 P: n/a ky******@gmail.com wrote: On Jul 25, 9:50 am, beginner Another question is how do I pass a tuple or list of all theaurgements of a function to the function. For example, I have all thearguments of a function in a tuple a=(1,2,3). Then I want to pass eachitem in the tuple to a function f so that I make a function callf(1,2,3). In perl it is a given, but in python, I haven't figured outa way to do it. (Maybe apply? but it is deprecated?) I'm not sure about the first question, but as for the second, you could do a few different things. You could just pass the tuple itself into the function and have the tuple unpacked inside the function. OR you could use the syntax invented for just that purpose ;). >>t = 1, 2, 3f(*t) bam! :) This works with dicts as well (for giving keyword arguments). There you prepend ** (two asterisk to your dict). Simple :) /W Jul 25 '07 #10

 P: n/a On Jul 25, 8:46 am, beginner >def foo(a, b, c): print a, b, c ... >>t = (1, 2, 3) >>foo(*t) 1 2 3 Have a look at the official tutorial, 4.7.4http://www.python.org/doc/ current/tut/node6.html#SECTION006740000000000000000 Thanks, cg HTH, Stargaming Hi Stargaming, I know the * operator. However, a 'partial unpack' does not seem to work. def g(): return (1,2) def f(a,b,c): return a+b+c f(*g(),10) will return an error. Do you know how to get that to work? You can use the "partial" method from functools: import functools sum_of_three = functools.partial(f, *g())(10) -- Hope this helps, Steven Jul 25 '07 #11

 P: n/a On Jul 25, 12:00 pm, kyoso...@gmail.com wrote: On Jul 25, 10:46 am, beginner def foo(a, b, c): print a, b, c ... >t = (1, 2, 3) >foo(*t) 1 2 3 Have a look at the official tutorial, 4.7.4http://www.python.org/doc/ current/tut/node6.html#SECTION006740000000000000000 Thanks, cg HTH, Stargaming Hi Stargaming, I know the * operator. However, a 'partial unpack' does not seem to work. def g(): return (1,2) def f(a,b,c): return a+b+c f(*g(),10) will return an error. Do you know how to get that to work? Thanks, cg As I mentioned, you can access the elements individually using square brackets. The following works: f(g(), g(), 10) But it's not clear. Unfortunately, I'm not seeing much else for tuple unpacking except the obvious: a,b=g() f(a,b,10) Mike Or if you'd rather write it in one line: f(*(g() + (10,))) George Jul 25 '07 #12

 P: n/a Here's a quick flatten() function: def flatten(obj): if type(obj) not in (list, tuple, str): raise TypeError("String, list, or tuple expected in flatten().") if len(obj) == 1: if type(obj) in (tuple, list): return flatten(obj) else: return [obj] else: return [obj] + flatten(obj[1:]) x = [1, 2, (3, 4)] y = (1, 2, [3, 4]) z = "It even works with strings!" d = {"foo": "bar", "baz": "bat"} print flatten(x) print flatten(y) print flatten(z) print flatten(d) Jul 25 '07 #13

 P: n/a On Jul 25, 10:33 am, Jeff >y = [(1,2),3,4]y [(1, 2), 3, 4] >>print flatten(y) [(1, 2), 3, 4] if the last line is changed to return flatten([obj]) + flatten(obj[1:]) then it will unpack tuples/lists anywhere in the main collection being flattened: >>y [(1, 2), 3, 4] >>flatten(y) [1, 2, 3, 4] >>z = [1,(2,3),4]flatten(z) [1, 2, 3, 4] >>x [1, 2, (3, 4)] >>flatten(x) [1, 2, 3, 4] >>k = [(1,2),(3,4)]flatten(k) [1, 2, 3, 4] Jul 25 '07 #14

 P: n/a On 2007-07-25, Jeff

 P: n/a On 2007-07-25, Neil Cerutti Here's a quick flatten() function:def flatten(obj): if type(obj) not in (list, tuple, str): raise TypeError("String, list, or tuple expected inflatten().") if len(obj) == 1: if type(obj) in (tuple, list): return flatten(obj) else: return [obj] else: return [obj] + flatten(obj[1:])x = [1, 2, (3, 4)]y = (1, 2, [3, 4])z = "It even works with strings!"d = {"foo": "bar", "baz": "bat"} e = [, 2, 3, , 4] Please excuse my bad typography. The above should've been e = [, 2, 3, 4]. -- Neil Cerutti It isn't pollution that is hurting the environment; it's the impurities in our air and water that are doing it. --Dan Quayle Jul 25 '07 #16

 P: n/a def flatten(listOfLists): return list(chain(*listOfLists)) >From http://www.python.org/doc/2.4/lib/it...s-recipes.html -- EduardoOPadoan (eopadoan->altavix::com) Bookmarks: http://del.icio.us/edcrypt Jul 25 '07 #17

 P: n/a Sorry about that. Hopefully, this should work ;) def flatten(obj): if type(obj) not in (list, tuple, str): raise TypeError("String, list, or tuple expected in flatten().") if len(obj) == 1: if type(obj) in (tuple, list): return flatten(obj) else: return [obj] else: if type(obj) in (list, tuple): return flatten(obj) + flatten(obj[1:]) else: return [obj] + flatten(obj[1:]) x = (1, 2, [3, 4, (5, 6)]) y = ([1, 2, (3, 4)], 5, 6) z = (1, [2, 3, (4, 5)], 6) print flatten(x) print flatten(y) print flatten(z) Jul 25 '07 #18

 P: n/a On Jul 25, 3:05 pm, "Eduardo \"EdCrypt\" O. Padoan" altavix::com) Bookmarks:http://del.icio.us/edcrypt That doesn't necessarily work: import itertools x = (1, 2, [3, 4, (5, 6)]) y = ([1, 2, (3, 4)], 5, 6) z = (1, [2, 3, (4, 5)], 6) def flatten(listOfLists): return list(itertools.chain(*listOfLists)) print flatten(x) print flatten(y) print flatten(z) ==TypeError: chain argument #1 must support iteration Jul 25 '07 #19

 P: n/a On Jul 25, 11:33 am, Paul Rubin

 P: n/a Also, this has not been suggested: > pydef g(): ... return (1,2) ... pydef f(a,b,c): ... return a+b+c ... pyf(c=10, *g()) 13 James- Hide quoted text - - Show quoted text - Great idea. Jul 26 '07 #21

 P: n/a Not the most beautiful solution, but it works. Diez- Hide quoted text - - Show quoted text - Yeah it works! Thanks. Jul 26 '07 #22

 P: n/a On Wed, 25 Jul 2007 15:46:58 +0000, beginner wrote: I know the * operator. However, a 'partial unpack' does not seem to work. def g(): return (1,2) def f(a,b,c): return a+b+c f(*g(),10) will return an error. No it doesn't, it _raises_ an exception. This is a function that returns an error: def function(): """Returns an error.""" return Error() # defined elsewhere But to answer your question: Do you know how to get that to work? It's a little bit messy, but this works: >>f(*(g() + (10,))) 13 This is probably easier to read: >>t = g() + (10,); f(*t) 13 -- Steven. Jul 26 '07 #23

 P: n/a On Wed, 25 Jul 2007 09:33:26 -0700, Paul Rubin wrote: Things are logically single values or they are logically lists of values Except for strings, and string-like objects. And files. And records/structs, and tuples. And lists. And sets. And bit strings. And tree-like structures. And, well, just about everything really. But apart from those minor exceptions, I agree completely with your recommendation. (Ha ha only serious.) -- Steven. Jul 26 '07 #24

 P: n/a For example, if I have the below structure: Big Record Small Record Type A Many Small Record Type B Small Record Type C It is pretty natural to use lists, although after a while it is difficult to figure out the meaning of the fields in the lists. If only there were a way to 'attach' names to members of the list. You could use dictionaries: big_record = { "small_record_a": { ... }, "many_small_record_b": { "sub_record_of_b": { ... }, "sub_record_of_b2": { ... }, }, "small_record_c": { ... }, } Jul 26 '07 #25

 P: n/a On Thu, 26 Jul 2007 00:58:10 +0000, beginner wrote: I need nested lists to represent nested records in a script. Since the structure of the underlying data is nested, I think it is probably reasonable to represent them as nested lists. For example, if I have the below structure: Big Record Small Record Type A Many Small Record Type B Small Record Type C It is pretty natural to use lists, although after a while it is difficult to figure out the meaning of the fields in the lists. If only there were a way to 'attach' names to members of the list. That's where you may start looking into classes. The simplest one is for just holding attributes seems to be the "bunch": In : class Bunch(object): ....: def __init__(self, **kwargs): ....: self.__dict__ = kwargs ....: In : small_a = Bunch(foo=42, bar=23) In : many_b = [1, 2, 3] In : small_c = Bunch(name='eric', profession='viking') In : big_record = Bunch(small_a=small_a, many_b=many_b, small_c=small_c) In : big_record.small_a.bar Out: 23 In : big_record.many_b Out: 2 For the unpacking question, I encountered it when working with list comprehensions. For example: [ f(*x,1,2) for x in list] is difficult to do if I don't want to expand *x to x..x[n]. There are usually 7-10 items in the list and it is very tedious and error prone. If you are the designer of `f` then just receive the whole `x` as *one* argument. Ciao, Marc 'BlackJack' Rintsch Jul 26 '07 #26

### This discussion thread is closed

Replies have been disabled for this discussion. 