Re: searching for strings (in a tuple) in a string

2006-07-14 Thread Simon Forman
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_ITER20 (to 30)
 10 STORE_FAST   0 (n)

  9  13 LOAD_FAST0 (n)
 16 JUMP_IF_TRUE 7 (to 26)
 19 POP_TOP
 20 LOAD_GLOBAL  2 (AssertionError)
 23 RAISE_VARARGS1
   26 POP_TOP
 27 JUMP_ABSOLUTE7
   30 POP_BLOCK
   31 LOAD_CONST   0 (None)
 34 RETURN_VALUE
===
 13   0 LOAD_GLOBAL  0 (False)
  3 LOAD_CONST   1 (code object generator
expression at 0xb7d89ca0, file delme.py, line 13)
  6 MAKE_FUNCTION0
  9 LOAD_GLOBAL  1 (N)
 12 GET_ITER
 13 CALL_FUNCTION1
 16 COMPARE_OP   7 (not in)
 19 JUMP_IF_TRUE 7 (to 29)
 22 POP_TOP
 23 LOAD_GLOBAL  2 (AssertionError)
 26 RAISE_VARARGS1
   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_ABSOLUTE7
   16 POP_BLOCK
   17 LOAD_CONST   0 (None)
 20 RETURN_VALUE
===
 13   0 LOAD_CONST   0 (None)
  3 RETURN_VALUE

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: searching for strings (in a tuple) in a string

2006-07-07 Thread Steven D'Aprano
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.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: searching for strings (in a tuple) in a string

2006-07-06 Thread [EMAIL PROTECTED]
You can get the matching elements with a list comprehension with
something like

py a='xfsdfyysd asd x'
py tup=('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?

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: searching for strings (in a tuple) in a string

2006-07-06 Thread Fredrik Lundh
manstey [EMAIL PROTECTED] wrote:

 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 



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: searching for strings (in a tuple) in a string

2006-07-06 Thread manstey
I know I can do it this way. I wanted to know if there was another way.

Fredrik Lundh wrote:
 manstey [EMAIL PROTECTED] wrote:

  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

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: searching for strings (in a tuple) in a string

2006-07-06 Thread Fredrik Lundh
manstey [EMAIL PROTECTED] wrote:

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 



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: searching for strings (in a tuple) in a string

2006-07-06 Thread Simon Forman
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

-- 
http://mail.python.org/mailman/listinfo/python-list