Declaring Unknown Type Variable in Python?

19,089

Solution 1

Very easy in Python. You need to get the type of the data in your list - use the type() function on the first item - type(argsList[0]). Then to initialize output (where you now have ????) you need the 'zero' or nul value for that type. So just as int() or float() or str() returns the zero or nul for their type so to will type(argsList[0])() return the zero or nul value for whatever type you have in your list.

So, here is your function with one minor modification:

def multiplyItemsByFour(argsList):
    output = type(argsList[0])()
    for arg in argsList:
        output += arg * 4
    return output

Works with:: argsList = [1, 2, 3, 4] or [1.0, 2.0, 3.0, 4.0] or "abcdef" ... etc,

Solution 2

def fivetimes(anylist):
  return anylist * 5

As you see, if you're given a list argument, there's no need for any assignment whatsoever in order to "multiply it a given number of times and return the output". You talk about a given list; how is it given to you, if not (the most natural way) as an argument to your function? Not that it matters much -- if it's a global variable, a property of the object that's your argument, and so forth, this still doesn't necessitate any assignment.

If you were "homeworkically" forbidden from using the * operator of lists, and just required to implement it yourself, this would require assignment, but no declaration:

def multiply_the_hard_way(inputlist, multiplier):
    outputlist = []
    for i in range(multiplier):
        outputlist.extend(inputlist)
    return outputlist

You can simply make the empty list "magicaly appear": there's no need to "declare" it as being anything whatsoever, it's an empty list and the Python compiler knows it as well as you or any reader of your code does. Binding it to the name outputlist doesn't require you to perform any special ritual either, just the binding (aka assignment) itself: names don't have types, only objects have types... that's Python!-)

Edit: OP now says output must not be a list, but rather int, float, or maybe string, and he is given no indication of what. I've asked for clarification -- multiplying a list ALWAYS returns a list, so clearly he must mean something different from what he originally said, that he had to multiply a list. Meanwhile, here's another attempt at mind-reading. Perhaps he must return a list where EACH ITEM of the input list is multiplied by the same factor (whether that item is an int, float, string, list, ...). Well then:

define multiply_each_item(somelist, multiplier):
  return [item * multiplier for item in somelist]

Look ma, no hands^H^H^H^H^H assignment. (This is known as a "list comprehension", btw).

Or maybe (unlikely, but my mind-reading hat may be suffering interference from my tinfoil hat, will need to go to the mad hatter's shop to have them tuned) he needs to (say) multiply each list item as if they were the same type as the first item, but return them as their original type, so that for example

>>> mystic(['zap', 1, 23, 'goo'], 2)
['zapzap', 11, 2323, 'googoo']
>>> mystic([23, '12', 15, 2.5], 2)
[46, '24', 30, 4.0]

Even this highly-mystical spec COULD be accomodated...:

>>> def mystic(alist, mul):
...   multyp = type(alist[0])
...   return [type(x)(mul*multyp(x)) for x in alist]
... 

...though I very much doubt it's the spec actually encoded in the mysterious runes of that homework assignment. Just about ANY precise spec can be either implemented or proven to be likely impossible as stated (by requiring you to solve the Halting Problem or demanding that P==NP, say;-). That may take some work ("prove the 4-color theorem", for example;-)... but still less than it takes to magically divine what the actual spec IS, from a collection of mutually contradictory observations, no examples, etc. Though in our daily work as software developer (ah for the good old times when all we had to face was homework!-) we DO meet a lot of such cases of course (and have to solve them to earn our daily bread;-).

EditEdit: finally seeing a precise spec I point out I already implemented that one, anyway, here it goes again:

def multiplyItemsByFour(argsList):
  return [item * 4 for item in argsList]

EditEditEdit: finally/finally seeing a MORE precise spec, with (luxury!-) examples:

Input: ('a','b') Output: 'aaaabbbb' Input: (2,3,4) Output: 36

So then what's wanted it the summation (and you can't use sum as it wouldn't work on strings) of the items in the input list, each multiplied by four. My preferred solution:

def theFinalAndTrulyRealProblemAsPosed(argsList):
  items = iter(argsList)
  output = next(items, []) * 4
  for item in items:
    output += item * 4
  return output

If you're forbidden from using some of these constructs, such as built-ins items and iter, there are many other possibilities (slightly inferior ones) such as:

def theFinalAndTrulyRealProblemAsPosed(argsList):
  if not argsList: return None
  output = argsList[0] * 4
  for item in argsList[1:]:
    output += item * 4
  return output

For an empty argsList, the first version returns [], the second one returns None -- not sure what you're supposed to do in that corner case anyway.

Solution 3

My guess is that the purpose of your homework is to expose you to "duck typing". The basic idea is that you don't worry about the types too much, you just worry about whether the behaviors work correctly. A classic example:

def add_two(a, b):
    return a + b

print add_two(1, 2)  # prints 3

print add_two("foo", "bar")  # prints "foobar"

print add_two([0, 1, 2], [3, 4, 5])  # prints [0, 1, 2, 3, 4, 5]

Notice that when you def a function in Python, you don't declare a return type anywhere. It is perfectly okay for the same function to return different types based on its arguments. It's considered a virtue, even; consider that in Python we only need one definition of add_two() and we can add integers, add floats, concatenate strings, and join lists with it. Statically typed languages would require multiple implementations, unless they had an escape such as variant, but Python is dynamically typed. (Python is strongly typed, but dynamically typed. Some will tell you Python is weakly typed, but it isn't. In a weakly typed language such as JavaScript, the expression 1 + "1" will give you a result of 2; in Python this expression just raises a TypeError exception.)

It is considered very poor style to try to test the arguments to figure out their types, and then do things based on the types. If you need to make your code robust, you can always use a try block:

def safe_add_two(a, b):
    try:
        return a + b
    except TypeError:
        return None

See also the Wikipedia page on duck typing.

Solution 4

Are you sure this is for Python beginners? To me, the cleanest way to do this is with reduce() and lambda, both of which are not typical beginner tools, and sometimes discouraged even for experienced Python programmers:

def multiplyItemsByFour(argsList):
    if not argsList:
        return None
    newItems = [item * 4 for item in argsList]
    return reduce(lambda x, y: x + y, newItems)

Like Alex Martelli, I've thrown in a quick test for an empty list at the beginning which returns None. Note that if you are using Python 3, you must import functools to use reduce().

Essentially, the reduce(lambda...) solution is very similar to the other suggestions to set up an accumulator using the first input item, and then processing the rest of the input items; but is simply more concise.

Solution 5

You don't need to declare variable types in python; a variable has the type of whatever's assigned to it.

EDIT:

To solve the re-stated problem, try this:

def multiplyItemsByFour(argsList):

output = argsList.pop(0) * 4

for arg in argsList:
        output += arg * 4

return output

(This is probably not the most pythonic way of doing this, but it should at least start off your output variable as the right type, assuming the whole list is of the same type)

Share:
19,089
Vineet v
Author by

Vineet v

I'm a programmer outside of Birmingham, AL. I write county government software.

Updated on June 14, 2022

Comments

  • Vineet v
    Vineet v almost 2 years

    I have a situation in Python(cough, homework) where I need to multiply EACH ELEMENT in a given list of objects a specified number of times and return the output of the elements. The problem is that the sample inputs given are of different types. For example, one case may input a list of strings whose elements I need to multiply while the others may be ints. So my return type needs to vary. I would like to do this without having to test what every type of object is. Is there a way to do this? I know in C# i could just use "var" but I don't know if such a thing exists in Python?

    I realize that variables don't have to be declared, but in this case I can't see any way around it. Here's the function I made:

    def multiplyItemsByFour(argsList):
    
    output = ????
    
    for arg in argsList:
            output += arg * 4
    
    return output
    

    See how I need to add to the output variable. If I just try to take away the output assignment on the first line, I get an error that the variable was not defined. But if I assign it a 0 or a "" for an empty string, an exception could be thrown since you can't add 3 to a string or "a" to an integer, etc...

    Here are some sample inputs and outputs:

    Input:  ('a','b')  Output:  'aaaabbbb'
    Input:  (2,3,4)    Output:  36
    

    Thanks!