Reputation: 5922
I'm a Python newbie, but I know that I can allow a variable number of multiple arguments in a function using *args
.
This script looks for a word
in any number of string *sources
:
def find(word, *sources):
for i in list(sources):
if word in i:
return True
source1 = "This is a string"
source2 = "This is Wow!"
if find("string", source1, source2) is True:
print "Succeed"
However, is it possible to specify "multiple" multiple arguments (*args
) in one function? In this case, that would be looking for multiple *words
in multiple *sources
.
As in, figuratively:
if find("string", "Wow!", source1, source2) is True:
print "Succeed"
else:
print "Fail"
How can I make the script discern what is intended to be a word
, and what's supposed to be a source
?
Upvotes: 3
Views: 1940
Reputation: 226674
The usual solution to needing "multiple multiple sources" is to have *args
be the first multiple and the second multiple being tuples.
>>> def search(target, *sources):
for i, source in enumerate(sources):
if target in source:
print('Found %r in %r' % (i, source))
return
print('Did not find %r' % target)
You will find other examples of this kind of API design used throughout the Python core language:
>>> help(str.endswith)
Help on method_descriptor:
endswith(...)
S.endswith(suffix[, start[, end]]) -> bool
Return True if S ends with the specified suffix, False otherwise.
With optional start, test S beginning at that position.
With optional end, stop comparing S at that position.
suffix can also be a tuple of strings to try.
>>> 'index.html'.endswith(('.xml', '.html', '.php'), 2)
True
>>> search(10, (5, 7, 9), (6, 11, 15), (8, 10, 14), (13, 15, 17))
Found 2 in (8, 10, 14)
Note that suffix can be a tuple of strings to try
.
Upvotes: 2
Reputation: 1124708
No, you can't, because you cannot distinguish where one type of element stops and the other starts.
Have your first argument accept either a single string or a sequence, instead:
def find(words, *sources):
if isinstance(words, str):
words = [words] # make it a list
# Treat words as a sequence in the rest of the function
Now you can call it either as:
find("string", source1, source2)
or
find(("string1", "string2"), source1, source2)
By passing in a sequence explicitly, you can distinguish it from the multiple sources as it is in essence just one argument.
Upvotes: 5