List membership in Python without "in"
How to define a function is_member() that takes a value (i.e. a number, string, etc) x and a list of values a, and returns True if x is a member of a, False otherwise. (Note that this is exactly what the in operator does, but for the sake of the exercise I should pretend Python did not have this operator.
This is what I've come 开发者_C百科up with, but it doesn't work!
def is_member(x, a):
return x == a[::]
I can think of two (edit: three) ways to do this:
First:
def is_member(array, value):
try:
array.index(value)
except ValueError:
return False
else:
return True
Second:
def is_member(array, value):
for item in array:
if item == value:
return True
return False
EDIT: Also, third:
def is_member(array, value):
return array.count(value) > 0
Recursive solution:
def is_member(value, array):
if len(array) == 0:
return False
return value == array[0] or is_member(value, array[1:])
Using a generator expression (note that this in
operator has nothing to do with the another one)
def is_member(x, a):
return any(x == y for y in a)
>>> is_member(10, xrange(1000000000000000))
True
You could simply just iterate over every element in the list then:
def is_member(col, a):
for i in xrange(len(col)):
if a == col[i]: return True
return False
>> a = [1,2,3,4]
>> is_member(a, 2)
True
>> is_member(a, 5)
False
Without using the "in" operator:
from itertools import imap
def is_member( item, array ):
return any( imap(lambda x: x == item, array ) )
which will cycle through the items of the list, one at a time, and short circuit when it hits a value that is True
.
Well, there are a lot of ways to do this, of course -- but you're a little hamstrung by the prohibition of "in" anywhere in the code. Here are a few things to try.
Variations on a theme ...
def is_member(item, seq):
return sum(map(lambda x: x == item, seq)) > 0
def is_member(item, seq):
return len(filter(lambda x: x != item, seq)) != len(seq)
You may have heard that asking for forgiveness is better than asking for permission ...
def is_member(item, seq):
try:
seq.index(item)
return True
except:
return False
Or something a little more functional-flavored ...
import itertools, operator, functools
def is_member(item, seq):
not_eq = functools.partial(operator.ne, item)
return bool(list(itertools.dropwhile(not_eq, seq)))
But, since your requirements preclude the use of the looping construct which would be most reasonable, I think the experts would recommend writing your own looping framework. Something like ...
def loop(action, until):
while True:
action()
if until():
break
def is_member(item, seq):
seq = seq
sigil = [False]
def check():
if seq[0] == item:
sigil[0] = True
def til():
seq.remove(seq[0])
return not len(seq)
loop(check, til)
return sigil[0]
Let us know how it goes.
精彩评论