473,386 Members | 1,817 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

comparing values in two sets

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.
May 14 '06 #1
11 11389

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
May 14 '06 #2
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

May 14 '06 #3
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

May 14 '06 #4
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

May 14 '06 #5
> 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
May 15 '06 #6
John Salerno <jo******@NOSPAMgmail.com> 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.
May 15 '06 #7
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. :)
May 15 '06 #8
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

May 15 '06 #9
Peter Otten <__*******@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!
May 15 '06 #10
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.

Thanks.


'enumerate' is another possibility:

s1 = 'abcd'
s2 = 'zzzz'
s3 = 'zbzz'
s4 = 'zzbz'

def are_itemwise_different( L1, L2 ):
#if len(L1) != len(L2): return True
for idx, value in enumerate(L1):
if value == L2[idx]:
return False
return True

#after Peter Otten
def are_itemwise_different( L1, L2 ):
#if len(L1) != len(L2): return True
return True not in ( value == L2[idx] for idx, value in
enumerate(L1) )

assert are_itemwise_different(s1,s2)
assert not are_itemwise_different(s1,s3)
assert are_itemwise_different(s1,s4)

def itemwise_intersect( L1, L2 ):
#if len(L1) != len(L2): raise
for idx, value in enumerate(L1):
if value == L2[idx]:
yield value

assert list(itemwise_intersect(s1,s2)) == []
assert list(itemwise_intersect(s1,s3)) == ['b']
assert list(itemwise_intersect(s1,s4)) == []

Gerard

May 15 '06 #11

Gerard Flanagan wrote:
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.

Thanks.


'enumerate' is another possibility:

s1 = 'abcd'
s2 = 'zzzz'
s3 = 'zbzz'
s4 = 'zzbz'

def are_itemwise_different( L1, L2 ):
#if len(L1) != len(L2): return True
for idx, value in enumerate(L1):
if value == L2[idx]:
return False
return True

#after Peter Otten
def are_itemwise_different( L1, L2 ):
return True not in ( val == L2[idx] for idx, val in enumerate(L1) )

assert are_itemwise_different(s1,s2)
assert not are_itemwise_different(s1,s3)
assert are_itemwise_different(s1,s4)


s1 = 'abcd'
s2 = 'zzzz'
s3 = 'zbzz'
s4 = 'zzbz'
s5 = 'xbxx'

def itemwise_intersect( L1, L2 ):
return [value for idx, value in set(enumerate(L1)) &
set(enumerate(L2))]

assert itemwise_intersect(s1,s2) == []
assert itemwise_intersect(s1,s3) == ['b']
assert itemwise_intersect(s1,s4) == []

def itemwise_intersect( *args ):
s = set(enumerate(args[0]))
for t in ( set(enumerate(X)) for X in args[1:]):
s.intersection_update(t)
return [val for i,val in s]

assert itemwise_intersect(s1,s3,s5) == ['b']

Gerard

May 15 '06 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Andy Fish | last post by:
Hi, I just found this template in someone else's xslt (it's Microsoft's "word2html" stylesheet to convert WordProcessingML to HTML) <xsl:template match="WX:sect"> <xsl:variable...
12
by: NickName | last post by:
I have the following situation. One set of data has 274 rows (set2) and anther has 264 (set1). Both data sets are similar in structure as well as values for both of them were extracts from the...
41
by: Odd-R. | last post by:
I have to lists, A and B, that may, or may not be equal. If they are not identical, I want the output to be three new lists, X,Y and Z where X has all the elements that are in A, but not in B, and...
19
by: Dennis | last post by:
I have a public variable in a class of type color declared as follows: public mycolor as color = color.Empty I want to check to see if the user has specified a color like; if mycolor =...
6
by: Paul Rubin | last post by:
I'm thinking of proposing that a values method be added to set objects, analogously with dicts. If x is a set, x.values() would be the same as list(x). This feels logical, and it would allow...
2
by: Yash | last post by:
Hi, We are in the process of tuning the performance of our stored procs in SQL 2000 and are looking for a tool that would help us in comparing the result sets of an old SP and a modified SP. The...
1
jenkinsloveschicken
by: jenkinsloveschicken | last post by:
Is it possible to compare a single value to many in a single statement? Here is what I am attempting to do: 1. Users lands on page and via a cookie check function they are identified. 2. A query...
0
by: DomiNeug | last post by:
Hello, Since a while i have to find a way of comparing "Sets" (multiple int Values) and so to find equal sets. There simply 3 tables ValueList with: ID int ValueListHasValue: ID int, ValueListID...
5
by: ASIM ABBAS | last post by:
EXPLAINATION: what if i have 3 set of values e.g 1,2,3,4,5 7,8,9,4,5 9,6,3,2,1 i want to use 3 variables a,b,c one for each set of values
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.