NorseMN
NorseMN

Reputation: 33

Passing a list of argument sets to a function

I've made a little progress on my understanding since submitting the poorly posed question below. I've gotten as far as this:

from collections import namedtuple
a = 3
Data = namedtuple('Data', 'b c')
d1 = Data(4,5)
d2 = Data(6,7)
data_list = (d1, d2)
def test1(a, *data) :
...

But *data is clearly not the correct syntax I seek for passing data_list. How do I structure this so the function knows that this is a namedtuple list, defined as Data.

In the function, I need to do something like: print 'A = ', a for each in data print 'BC = ', data.b + data.c


Original question below.

I'm an old hand at C, but new to Python, so my perspective is likely misaligned. I need to call a function with a couple of variables, and a list of a predefined set of values. I imagine something like this:

class TestData
    def __init__(self, input, delay, result)
    self.input = input
    self.delay = delay
    self.result = result

#                (input, delay, result)
TestData list = [
                 (11, 250, 42)
                 (22, 500, 123)
                 (37, 100, 97)
                ]

RunTest(id, channel, list)
    setup(id, channel)
    for each in list
        ...

Can this work? Or am I headed in the wrong direction?

Please excuse me if I haven't entered the example code with the correct formatting.

Upvotes: 3

Views: 366

Answers (3)

onlynone
onlynone

Reputation: 8289

I can see a number of problems with the code you posted, I think you have more issues than just how to pass a list of values to a function.

Your TestData class looks perfectly fine, but this code won't work:

TestData list = [
                 (11, 250, 42)
                 (22, 500, 123)
                 (37, 100, 97)
                ]

If you're trying to create a new instance of TestData, you'd want:

list = TestData(
    (11, 250, 42),
    (22, 500, 123),
    (37, 100, 97)
    )

A couple notes here:

  1. You probably don't want to call a local variable list since that'll clash with the list() global list class.
  2. You're not passing a list of arguments to the TestData constructor, you're sending 3 separate arguments, each of which is a tuple.
  3. Tuples are basically immutable lists (you can't reassign values in a tupe, you can't resize a tuple), and are constructed with (a,b) whereas lists are constructed with [a,b]

Next is this code:

RunTest(id, channel, list)
    setup(id, channel)
    for each in list

What is RunTest supposed to be? a function? a class? If it's a function, you'd want:

def RunTest(id, channel, list):

Note the leading def to define a function and the trailing : to start a new block of code. It's also python convention that only classes use CammelCase, functions should use snake_case.

What does your setup function look like? You don't give it here.

The code for each in list needs a trailing colon and you shouldn't use each, it's not necessary for a python for loop. The identifier in that position will have the element from each iteration over list. You probably want something like:

for item in list:
    do_something(item)

But that's also assuming that list is an iterable. If you really wanted list to be an instance of your TestData class, it's likely not iterable. Did you want to loop over each item from list.input?

Upvotes: 1

cs95
cs95

Reputation: 402553

Setup

class TestData:
     def __init__(self, inp, delay, result):
         self.input = inp
         self.delay = delay
         self.result = result

_list = [
  (11, 250, 42),
  (22, 500, 123),
  (37, 100, 97)
 ]

Use a list comprehension to create your objects, passing data at each iteration to the constructor:

>>> [TestData(*x) for x in _list]
[<__main__.TestData at 0x140b47eb8>,
 <__main__.TestData at 0x140b472b0>,
 <__main__.TestData at 0x140b474e0>]

Or, in a similar fashion, using a for loop:

>>> o_list = []
>>> for x in _list:
...    o_list.append(TestData(*x))
...
>>> o_list
[<__main__.TestData at 0x143d8a1d0>,
 <__main__.TestData at 0x143d8a2b0>,
 <__main__.TestData at 0x143d8a278>]

Upvotes: 4

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798696

It can work, but not like that.

tdparams = [ ... ]

 ...

tdseq = [TestData(*params) for params in tdparams]

Upvotes: 0

Related Questions