How to Wrap a Function That Only Takes Individual Elements to Make It Take a List

how to wrap a function that only takes individual elements to make it take a list

You are looking for do.call:

f <- function(x,y,z)x+y+z
do.call(f,list(1,2,3))
[1] 6

python, wrap and object into a list if not is an iterable

Your approach is good: It would cast a string object to an iterable though

try:
iter(obj)
except TypeError, te:
obj = list(obj)

Another thing you can check for is:

if not hasattr(obj, "__iter__"): #returns True if type of iterable - same problem with strings
obj = list(obj)
return obj

To check for string types:

import types
if not isinstance(obj, types.StringTypes) and hasattr(obj, "__iter__"):
obj = list(obj)
return obj

Handle either a list or single integer as an argument

Actually I agree with Andrew Hare's answer, just pass a list with a single element.

But if you really must accept a non-list, how about just turning it into a list in that case?

def select_rows(to_select):
if type(to_select) is not list: to_select = [ to_select ]

for row in range(0, table.numRows()):
if _table.item(row, 1).text() in to_select:
table.selectRow(row)

The performance penalty for doing 'in' on a single-item list isn't likely to be high :-)
But that does point out one other thing you might want to consider doing if your 'to_select' list may be long: consider casting it to a set so that lookups are more efficient.

def select_rows(to_select):
if type(to_select) is list: to_select = set( to_select )
elif type(to_select) is not set: to_select = set( [to_select] )

for row in range(0, table.numRows()):
if _table.item(row, 1).text() in to_select:
table.selectRow(row)

How to pass a list as an input of a function in Python

You are currently returning a value from your function in the first iteration of your for loop. Because of this, the second and third iteration of your for loop never take place. You need to move your return statement outside of the loop as follows:

import math

def square(x):
result = []
for y in x:
result.append(math.pow(y,2.0))
return result

print(square([1,2,3]))

Output

[1.0, 4.0, 9.0]

How to wrap a variadic function in C

The behaviour of your code is undefined.

sd_notifyf is a variadic function not a function taking as the last parameter va_list

int sd_notifyf( int unset_environment,
const char *format,
…);

I am afraid that you can not write the wrapper function as there is no version of the sd_notify function which takes va_list

You can only use the macro definition for that.

#define wrapperMacro(unset_environment, format, ...)\
do{\
/* do some stuff */\
sd_notifyf(unset_environment, format, __VA_ARGS__);\
}while(0)

You can also use string printf function (in this case vsnprintf):

#define LARGE_ENOUGH_TO_ACCOMODATE_THE_STRING 64

void wrapperFunc(int unset_environment, const char *format, ...) {
va_list list;
va_start(list, format);
char buff[LARGE_ENOUGH_TO_ACCOMODATE_THE_STRING];

vsnprintf(buff, sizeof(buff), format, list);

sd_notify(unset_environment, buff);

va_end(list);
}

Print list without brackets in a single row

print(', '.join(names))

This, like it sounds, just takes all the elements of the list and joins them with ', '.

Passing list elements as parameters to curried function

Paul Johnson's answer pretty much covers it. Just do

quadsum 4 3 2

and the result will be the function you want, with type Integer -> Integer.

But sometimes this isn't good enough. Sometimes you get lists of numbers, you don't know how long the lists are, and you need to apply the elements to your function. This is a bit harder. You can't do:

magicalFunction2 f [] = f
magicalFunction2 f (x1:x2:xs) = f x1 x2

because the results have different types. In the first case the result needs two arguments, and in the second it's a fully-applied function so no more arguments are allowed. In this case, the best thing to do is hold onto the list and your original function until enough arguments are available:

type PAPFunc f a result = Either (f, [a]) result

magicfunc f xs = Left (f,xs)

apply (Left (f,xs)) ys = Left (f,xs++ys)
apply p _ = p

simp2 :: PAPFunc (a->a->b) a b -> PAPFunc (a->a->b) a b
simp2 (Left (f,(x1:x2:xs))) = Right (f x1 x2)
simp2 p = p

now you can do:

Main> let j = magicfunc (+) []
Main> let m = apply j [1]
Main> let n = apply m [2,3]

Main> either (const "unfinished") show $ simp2 m
"unfinished"
Main> either (const "unfinished") show $ simp2 n
"3"

You'll need a separate simplify function for each arity, a problem that's most easily fixed by Template Haskell.

Using lists of arguments (as opposed to an argument of lists) tends to be very awkward in Haskell because the multiple results all have different types, and there's very little support for collections with variable numbers of differently-typed arguments. I've seen three general categories of solutions:

  1. Explicitly code for each case
    separately (quickly becomes a lot of
    work).

  2. Template Haskell.

  3. Type system hackery.

My answer mostly deals with trying to make 1 less painful. 2 and 3 are not for the faint of heart.

Edit: It turns out that there are some packages on Hackage that are related to this problem. Using "iteratee":

import qualified Data.Iteratee as It
import Control.Applicative

magic4 f = f <$> It.head <*> It.head <*> It.head <*> It.head

liftedQuadsum = magic4 quadsum
-- liftedQuadsum is an iteratee, which is essentially an accumulating function
-- for a list of data

Main> p <- It.enumChunk (It.Chunk [1]) liftedQuadsum
Main> It.run p
*** Exception: EofException
Main> q <- It.enumChunk (It.Chunk [2,3,4]) p
Main> It.run q
10

But "iteratee" and "enumerator" are likely overkill though.

How do I make function decorators and chain them together?

Check out the documentation to see how decorators work. Here is what you asked for:

from functools import wraps

def makebold(fn):
@wraps(fn)
def wrapper(*args, **kwargs):
return "<b>" + fn(*args, **kwargs) + "</b>"
return wrapper

def makeitalic(fn):
@wraps(fn)
def wrapper(*args, **kwargs):
return "<i>" + fn(*args, **kwargs) + "</i>"
return wrapper

@makebold
@makeitalic
def hello():
return "hello world"

@makebold
@makeitalic
def log(s):
return s

print hello() # returns "<b><i>hello world</i></b>"
print hello.__name__ # with functools.wraps() this returns "hello"
print log('hello') # returns "<b><i>hello</i></b>"

How do I make a flat list out of a list of lists?

Given a list of lists l,

flat_list = [item for sublist in l for item in sublist]

which means:

flat_list = []
for sublist in l:
for item in sublist:
flat_list.append(item)

is faster than the shortcuts posted so far. (l is the list to flatten.)

Here is the corresponding function:

def flatten(l):
return [item for sublist in l for item in sublist]

As evidence, you can use the timeit module in the standard library:

$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in l for item in sublist]'
10000 loops, best of 3: 143 usec per loop
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(l, [])'
1000 loops, best of 3: 969 usec per loop
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'reduce(lambda x,y: x+y,l)'
1000 loops, best of 3: 1.1 msec per loop

Explanation: the shortcuts based on + (including the implied use in sum) are, of necessity, O(L**2) when there are L sublists -- as the intermediate result list keeps getting longer, at each step a new intermediate result list object gets allocated, and all the items in the previous intermediate result must be copied over (as well as a few new ones added at the end). So, for simplicity and without actual loss of generality, say you have L sublists of I items each: the first I items are copied back and forth L-1 times, the second I items L-2 times, and so on; total number of copies is I times the sum of x for x from 1 to L excluded, i.e., I * (L**2)/2.

The list comprehension just generates one list, once, and copies each item over (from its original place of residence to the result list) also exactly once.

How to do multiple arguments to map function where one remains the same

One option is a list comprehension:

[add(x, 2) for x in [1, 2, 3]]

More options:

a = [1, 2, 3]

import functools
map(functools.partial(add, y=2), a)

import itertools
map(add, a, itertools.repeat(2, len(a)))


Related Topics



Leave a reply



Submit