Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > comparing values in two sets

Reply
Thread Tools

comparing values in two sets

 
 
John Salerno
Guest
Posts: n/a
 
      05-14-2006
I'd like to compare the values in two different sets to test if any of
the positions in either set share the same value (e.g., if the third
element of each set is an 'a', then the test fails).

I have this:

def test_sets(original_set, trans_letters):
for pair in zip(original_set, trans_letters):
if pair[0] == pair[1]:
return False
return True


zip() was the first thing I thought of, but I was wondering if there's
some other way to do it, perhaps a builtin that actually does this kind
of testing.

Thanks.
 
Reply With Quote
 
 
 
 
skip@pobox.com
Guest
Posts: n/a
 
      05-14-2006

John> I'd like to compare the values in two different sets to test if
John> any of the positions in either set share the same value (e.g., if
John> the third element of each set is an 'a', then the test fails).

Do you really mean "set" and not "list"? Note that they are unordered.
These two sets are equal:

set(['b', 'a', 'c'])

set(['a', 'b', 'c'])

Skip
 
Reply With Quote
 
 
 
 
bearophileHUGS@lycos.com
Guest
Posts: n/a
 
      05-14-2006
Note that you are comparing ordered sequences, like lists, tuples,
strings, etc, and not sets. Something like this can be a little
improvement of your code, it avoids building the zipped list, and scans
the iterable unpacking it on the fly:

from itertools import izip
def test_sets(original_set, trans_letters):
for elem1, elem2 in izip(original_set, trans_letters):
if elem1 == elem2:
return False
return True

Bye,
bearophile

 
Reply With Quote
 
bearophileHUGS@lycos.com
Guest
Posts: n/a
 
      05-14-2006
So you probably have to change the function test_sets name, because
it's not much useful on real sets.

Can't you use the == or != operators on those sequences?

Bye,
bearophile

 
Reply With Quote
 
John Machin
Guest
Posts: n/a
 
      05-14-2006
John Salerno wrote:
> I'd like to compare the values in two different sets to test if any of
> the positions in either set share the same value (e.g., if the third
> element of each set is an 'a', then the test fails).
>
> I have this:
>
> def test_sets(original_set, trans_letters):
> for pair in zip(original_set, trans_letters):
> if pair[0] == pair[1]:
> return False
> return True
>
>
> zip() was the first thing I thought of, but I was wondering if there's
> some other way to do it, perhaps a builtin that actually does this kind
> of testing.


There is no such concept as "position in [a] set". Sets in
math[s]/logic are *NOT* ordered. The order in which Python retrieves
elements when you do (for example) list(a_set) is a meaningless
artefact of the implementation du jour, and is not to be relied on.

>>> s = set(['xyzzy', 'plugh', 'sesame'])
>>> t = set(['xyzzy', 'plugh', 'mellon'])
>>> s

set(['sesame', 'plugh', 'xyzzy'])
>>> t

set(['plugh', 'mellon', 'xyzzy'])
>>> zip(s, t)

[('sesame', 'plugh'), ('plugh', 'mellon'), ('xyzzy', 'xyzzy')]
>>>


You may need one or more of these:
>>> s & t

set(['plugh', 'xyzzy'])
>>> s ^ t

set(['sesame', 'mellon'])
>>> s | t

set(['sesame', 'plugh', 'mellon', 'xyzzy'])
>>> (s | t) - t

set(['sesame'])
>>> (s | t) - s

set(['mellon'])
>>>


If that doesn't meet your needs:
back up a level and tell us what you are trying to achieve

If True:
read about sets in the Python docs

HTH,
John

 
Reply With Quote
 
Tim Chase
Guest
Posts: n/a
 
      05-15-2006
> I'd like to compare the values in two different sets to
> test if any of the positions in either set share the same
> value (e.g., if the third element of each set is an 'a',
> then the test fails).


There's an inherant problem with this...sets by definition
are unordered, much like dictionaries. To compare them my
such means, you'd have to convert them to lists, sort the
lists by some ordering, and then compare the results.
Something like

s1 = set([1,3,5,7,9])
s2 = set([1,2,3])
list1 = list(s1)
list2 = list(s2)
list1.sort()
list2.sort()

if [(x,y) for x,y in zip(list1,list2) if x == y]:
print "There's an overlap"
else:
print "No matching elements"


Just to evidence matters, on my version of python (2.3.5 on
Debian), the following came back:

>>> set([1,3,5,7,9])

set([1,3,9,5,7])

That's not the original order, but the definition of a set
isn't hurt/changed by any ordering.

Thus, asking for the "position in a set" is an undefined
operation.

-tkc

PS: for the above was done in 2.3.5 using this line:
from sets import Set as set
 
Reply With Quote
 
Paul Rubin
Guest
Posts: n/a
 
      05-15-2006
John Salerno <> writes:
> I'd like to compare the values in two different sets to test if any of
> the positions in either set share the same value (e.g., if the third
> element of each set is an 'a', then the test fails).


I think by "sets" you mean "lists". Sets are unordered, as a few
people have mentioned.

> I have this:
>
> def test_sets(original_set, trans_letters):
> for pair in zip(original_set, trans_letters):
> if pair[0] == pair[1]:
> return False
> return True


That's fairly reasonable. You could use itertools.izip instead of
zip, which makes a generator instead of building up a whole new list
in memory. A more traditional imperative-style version would be
something like:

def test_sets(original_set, trans_letters):
for i in xrange(len(original_set)):
if original_set[i] == trans_letters[i]:
return True
return False

You could even get cutesy and say something like (untested):

from itertools import izip
def test_sets(original_set, trans_letters):
return not sum(a==b for a,b in izip(original_set, trans_letters))

but that can be slower since it always scans both lists in entirety,
even if a matching pair of elements is found right away.

I don't offhand see a builtin function or not-too-obscure one-liner
that short-circuits, but maybe there is one.

Note that all the above examples assume the two lists are the same
length. Otherwise, some adjustment is needed.
 
Reply With Quote
 
John Salerno
Guest
Posts: n/a
 
      05-15-2006
John Salerno wrote:
> I'd like to compare the values in two different sets


Oops, I guess I was a little too loose in my use of the word 'set'. I'm
using sets in my program, but by this point they actually become
strings, so I'm really comparing strings.

Thanks for pointing that out to me, and I'll look into izip as well. I
was wondering if I could use an iterator for this somehow.
 
Reply With Quote
 
Peter Otten
Guest
Posts: n/a
 
      05-15-2006
Paul Rubin wrote:

> You could even get cutesy and say something like (untested):
>
> from*itertools*import*izip
> def*test_sets(original_set,*trans_letters):
> return*not*sum(a==b*for*a,b*in*izip(original_set,*trans_letters))
>
> but that can be slower since it always scans both lists in entirety,
> even if a matching pair of elements is found right away.


Here's a variant that does performs only the necessary tests:

>>> from itertools import izip
>>> True not in (a == b for a, b in izip(range(3), range(3)))

False

A "noisy" equality test to demonstrate short-circuiting behaviour:

>>> def print_eq(a, b):

.... print "%r == %r --> %r" % (a, b, a == b)
.... return a == b
....
>>> True not in (print_eq(a, b) for a, b in izip(range(3), range(3)))

0 == 0 --> True
False
>>> True not in (print_eq(a, b) for a, b in izip(["x", 1, 2], range(3)))

'x' == 0 --> False
1 == 1 --> True
False
>>> True not in (print_eq(a, b) for a, b in izip(["x", "x", "x"], range(3)))

'x' == 0 --> False
'x' == 1 --> False
'x' == 2 --> False
True

Peter

 
Reply With Quote
 
Paul Rubin
Guest
Posts: n/a
 
      05-15-2006
Peter Otten <__peter__@web.de> writes:
> Here's a variant that does performs only the necessary tests:
>
> >>> from itertools import izip
> >>> True not in (a == b for a, b in izip(range(3), range(3)))


Cute!
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
two axis, two data sets GD::Graphic java Perl Misc 7 12-08-2006 12:55 PM
xpath: comparing two node sets Andy Fish XML 3 03-10-2005 09:16 AM
Comparing values in 2 textfiles and returning the missing values Jorgen Gustafsson Perl 4 12-12-2003 09:09 AM
suggestions for comparing two large data sets requested Terry L. Ridder Perl Misc 4 10-14-2003 10:28 PM
Comparing node sets Doug XML 1 07-25-2003 03:02 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57