By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,441 Members | 1,468 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,441 IT Pros & Developers. It's quick & easy.

searching for strings (in a tuple) in a string

P: n/a
Hi,

I often use:

a='yy'
tup=('x','yy','asd')
if a in tup:
<...>

but I can't find an equivalent code for:

a='xfsdfyysd asd x'
tup=('x','yy','asd')
if tup in a:
< ...>

I can only do:

if 'x' in a or 'yy' in a or 'asd' in a:
<...>

but then I can't make the if clause dependent on changing value of tup.

Is there a way around this?

Jul 6 '06 #1
Share this Question
Share on Google+
7 Replies


P: n/a
You can get the matching elements with a list comprehension with
something like

pya='xfsdfyysd asd x'
pytup=('x','yy','asd')
py[x for x in tup if x in a.split()]
['x', 'asd']

Hope this helps

manstey wrote:
Hi,

I often use:

a='yy'
tup=('x','yy','asd')
if a in tup:
<...>

but I can't find an equivalent code for:

a='xfsdfyysd asd x'
tup=('x','yy','asd')
if tup in a:
< ...>

I can only do:

if 'x' in a or 'yy' in a or 'asd' in a:
<...>

but then I can't make the if clause dependent on changing value of tup.

Is there a way around this?
Jul 6 '06 #2

P: n/a
"manstey" <ma*****@csu.edu.auwrote:
but I can't find an equivalent code for:

a='xfsdfyysd asd x'
tup=('x','yy','asd')
if tup in a:
< ...>

I can only do:

if 'x' in a or 'yy' in a or 'asd' in a:
<...>

but then I can't make the if clause dependent on changing value of tup.

Is there a way around this?
is the "def" statement broken in your Python version ?

def findany(text, words):
for w in words:
if w in text:
return True
return False

if findany(a, tup):
...

</F>

Jul 6 '06 #3

P: n/a
I know I can do it this way. I wanted to know if there was another way.

Fredrik Lundh wrote:
"manstey" <ma*****@csu.edu.auwrote:
but I can't find an equivalent code for:

a='xfsdfyysd asd x'
tup=('x','yy','asd')
if tup in a:
< ...>

I can only do:

if 'x' in a or 'yy' in a or 'asd' in a:
<...>

but then I can't make the if clause dependent on changing value of tup.

Is there a way around this?

is the "def" statement broken in your Python version ?

def findany(text, words):
for w in words:
if w in text:
return True
return False

if findany(a, tup):
...

</F>
Jul 6 '06 #4

P: n/a
"manstey" <ma*****@csu.edu.auwrote:
>I know I can do it this way. I wanted to know if there was another way.
if you don't want to write Python programs, why are you using Python ?

</F>

Jul 6 '06 #5

P: n/a
manstey wrote:
Hi,

I often use:

a='yy'
tup=('x','yy','asd')
if a in tup:
<...>

but I can't find an equivalent code for:

a='xfsdfyysd asd x'
tup=('x','yy','asd')
if tup in a:
< ...>

I can only do:

if 'x' in a or 'yy' in a or 'asd' in a:
<...>

but then I can't make the if clause dependent on changing value of tup.

Is there a way around this?
One thing I do sometimes is to check for True in a generator
comprehension

if True in (t in a for t in tup):
# do whatever here
Because you're using a generator you get the same "short-circut"
behavior that you would with a series of 'or's, the if statement won't
bother checking the rest of the terms in tup after the first True
value.
>>def f(n, m):
print n
return n m
>>m = 2
if True in (f(n, m) for n in range(5)):
print 'done'
0
1
2
3
done

# See? No 4! :-)
I usually use this with assert statements when I need to check a
sequence. Rather than:

for something in something_else: assert expression

I say

assert False not in (expression for something in something_else)

This way the whole assert statement will be removed if you use the '-O'
switch to the python interpreter. (It just occurred to me that that's
just an assumption on my part. I don't know for sure that the
interpreter isn't smart enough to remove the first form as well. I
should check that. ;P )

Note, in python 2.5 you could just say

if any(t in a for t in tup):
# do whatever here
In your case though, if I were doing this kind of thing a lot, I would
use a little helper function like the findany() function Fredrik Lundh
posted.

IMHO

if findany(a, tup):
...

is much clearer and readily understandable than mucking about with
generator comprehensions...
Peace,
~Simon

Jul 6 '06 #6

P: n/a
On Thu, 06 Jul 2006 04:45:35 -0700, manstey wrote:
Hi,

I often use:

a='yy'
tup=('x','yy','asd')
if a in tup:
<...>

but I can't find an equivalent code for:

a='xfsdfyysd asd x'
tup=('x','yy','asd')
if tup in a:
< ...>
Of course you can't. Strings don't contain tuples, since they are utterly
different kinds of objects.
I can only do:

if 'x' in a or 'yy' in a or 'asd' in a:
<...>

but then I can't make the if clause dependent on changing value of tup.
Sure you can.

a = 'xfsdfyysd asd x'
tup = ('x','yy','asd')
for item in tup:
if item not in a:
print "Item missing"
break
else:
print "All items found."

It's a little verbose, but you can stick it into a function definition and
use it as a one-liner.

Or, use a list comprehension:

a = 'xfsdfyysd asd x'
tup = ('x','yy','asd')
if [item for item in tup if item in a]:
print "Some items found."
else:
print "No items found."

Or, you can use filter:

a = 'xfsdfyysd asd x'
tup = ('x','yy','asd')
if filter(lambda item, a=a: item in a, tup):
print "Some items found."
else:
print "No items found."
However, keep in mind that "in" has a subtly different effect in strings
and tuples.

"x" in ("x", "y") is true, but "x" in ("xy", "yy") is not, as you would
expect. However, the situation for strings isn't quite the same:
"x" in "x y" is true, but so is "x" in "xx yy".

One way around that is to convert your string a into a list:

a = 'xfsdfyysd asd x'
a = a.split() # split on any whitespace

and now your tests will behave as you expected.

--
Steven.

Jul 7 '06 #7

P: n/a
Simon Forman wrote:
....
I usually use this with assert statements when I need to check a
sequence. Rather than:

for something in something_else: assert expression

I say

assert False not in (expression for something in something_else)

This way the whole assert statement will be removed if you use the '-O'
switch to the python interpreter. (It just occurred to me that that's
just an assumption on my part. I don't know for sure that the
interpreter isn't smart enough to remove the first form as well. I
should check that. ;P )
FWIW I did just check that and it seems valid, the second form gets
"optimized" away.

File delme.py:
import dis

N = (True, True, False)

def a():
for n in N:
assert n

def b():
assert False not in (n for n in N)

dis.dis(a)
print '==============================='
dis.dis(b)
Results of running it without '-O':
$ python delme.py
8 0 SETUP_LOOP 28 (to 31)
3 LOAD_GLOBAL 0 (N)
6 GET_ITER
> 7 FOR_ITER 20 (to 30)
10 STORE_FAST 0 (n)

9 13 LOAD_FAST 0 (n)
16 JUMP_IF_TRUE 7 (to 26)
19 POP_TOP
20 LOAD_GLOBAL 2 (AssertionError)
23 RAISE_VARARGS 1
> 26 POP_TOP
27 JUMP_ABSOLUTE 7
> 30 POP_BLOCK
31 LOAD_CONST 0 (None)
34 RETURN_VALUE
===============================
13 0 LOAD_GLOBAL 0 (False)
3 LOAD_CONST 1 (<code object <generator
expressionat 0xb7d89ca0, file "delme.py", line 13>)
6 MAKE_FUNCTION 0
9 LOAD_GLOBAL 1 (N)
12 GET_ITER
13 CALL_FUNCTION 1
16 COMPARE_OP 7 (not in)
19 JUMP_IF_TRUE 7 (to 29)
22 POP_TOP
23 LOAD_GLOBAL 2 (AssertionError)
26 RAISE_VARARGS 1
> 29 POP_TOP
30 LOAD_CONST 0 (None)
33 RETURN_VALUE
Results of running it with '-O':
$ python -O delme.py
8 0 SETUP_LOOP 14 (to 17)
3 LOAD_GLOBAL 0 (N)
6 GET_ITER
> 7 FOR_ITER 6 (to 16)
10 STORE_FAST 0 (n)

9 13 JUMP_ABSOLUTE 7
> 16 POP_BLOCK
17 LOAD_CONST 0 (None)
20 RETURN_VALUE
===============================
13 0 LOAD_CONST 0 (None)
3 RETURN_VALUE

Jul 14 '06 #8

This discussion thread is closed

Replies have been disabled for this discussion.