# set operations on sets with more than one of the same member

• (3 Pages)
• 1
• 2
• 3

## 38 Replies - 2015 Views - Last Post: 13 March 2018 - 01:54 PMRate Topic: //<![CDATA[ rating = new ipb.rating( 'topic_rate_', { url: 'https://www.dreamincode.net/forums/index.php?app=forums&module=ajax&section=topics&do=rateTopic&t=409731&amp;s=76abda86b4a966b4fc33cf5dac227a25&md5check=' + ipb.vars['secure_hash'], cur_rating: 0, rated: 0, allow_rate: 0, multi_rate: 1, show_rate_text: true } ); //]]>

### #1 bobsmith76

Reputation: 9
• Posts: 211
• Joined: 14-February 17

# set operations on sets with more than one of the same member

Posted 07 March 2018 - 12:42 PM

I simply love Python's set operations. These things make life so much easier. In any case, one of the problem I'm having is what to do when you have a list where it's important how many times the same member repeats itself. For example, I'm going to be doing this operation a lot where I have to determine if one list is in another list. Below list 2 is not in list1 because list2 has the number 3 twice. You can't convert list1 and list2 into sets because the fact that there are two 3's is important. The best way I came up with to determine whether or not list2 is not in list1 is to use remove. But I would eventually have to use the deepcopy method because I'm going to be using list1 several times and the remove method mutates it. Plus the method I used is 5 lines which is too many in my book. The best work around I came up with is below that with set1 and set2. For those strings that repeat themselves I just make them unique with a number. Does anyone know of a better method because even method 2 is slightly long winded.

```list1 = [1, 2, 3, 4, 5]
list2 = [5, 3, 3]

try:
for x in list2: list1.remove(x)
bool1 = True
except:
bool1 = False

set1 = {'Hs', "Ho", "Ho1", "Lo"}
set2 = {"Ho", "Ho1", "Lo", "Ms", "Ns", "Hs"}

if len(set1 - set2) == 0:
bool1 = True
else:
bool1 = False

```

Is This A Good Question/Topic? 0

## Replies To: set operations on sets with more than one of the same member

### #2 ndc85430

• I think you'll find it's "Dr"

Reputation: 824
• Posts: 3,335
• Joined: 13-June 14

## Re: set operations on sets with more than one of the same member

Posted 07 March 2018 - 12:53 PM

bobsmith76, on 07 March 2018 - 07:42 PM, said:

Plus the method I used is 5 lines which is too many in my book.

I'm extremely tired right now, so probably can't give much input on the main question, but this is concerning. Why are 5 lines too many? I'd think a function having that many lines is perfectly readable, assuming the complexity of those lines is very low. Why obsess about making things as short as possible? That's going to hurt readability.

### #3 DK3250

• Pythonian

Reputation: 406
• Posts: 1,312
• Joined: 27-December 13

## Re: set operations on sets with more than one of the same member

Posted 08 March 2018 - 10:46 AM

You have a strange habit of showing working code and then ask for shorter versions. But shorter does not necessarily mean better.

In your first code snippet you use a try-except block to catch a ValueError exception (x not in list). I my world try-except should not be used if a simple if-statement can do it:
```list1 = [1, 2, 3, 4, 5]
list2 = [5, 3, 3]

def sub_lst(list1, list2):
lst = list1.copy()
for x in list2:
if x in lst:  # this makes the try-except block obsolete
lst.remove(x)
else:
return False
return True

print(sub_lst(list1, list2))
```
Not shorter, but (in my opinion) better..!

As you are a fully adequate programmer yourself, I will just leave a link and let it be up to you if this is a path to pursue.

This post has been edited by DK3250: 08 March 2018 - 10:49 AM

### #4 DK3250

• Pythonian

Reputation: 406
• Posts: 1,312
• Joined: 27-December 13

## Re: set operations on sets with more than one of the same member

Posted 08 March 2018 - 11:18 AM

Oh, your second code snippet (with sets) is unclear.
It will return 'True', but set2 is not a subset of set1.
Or, maybe, I've misunderstood your intentions...?

### #5 jon.kiparsky

• Beginner

Reputation: 11069
• Posts: 18,906
• Joined: 19-March 11

## Re: set operations on sets with more than one of the same member

Posted 08 March 2018 - 11:27 AM

If you want to represent a "multiset", you might consider using a Counter as your starting point.
```>>> from collections import Counter
>>> counts = Counter([1,2,2,3,3,3,4,4,4,"five", "five"])
>>> counts
>>> other_counts = Counter([1,1,2,"six"])
>>> other_counts
Counter({1: 2, 2: 1, 'six': 1})
>>>

```

Clearly you could then say that a union of those two "sets" would look like Counter({3: 3, 4: 3, 'five': 2, 'six': 1, 2: 4, 1: 3})
Intersection would presumably be Counter({2: 1, 1: 1})

You can probably work out what the other standard set operations would look like.

This would be a fun class to write. It would involve more than five lines of code, but at the end of it you'd be able to create and work with MultiSet objects, and that'd be fun.

### #6 DK3250

• Pythonian

Reputation: 406
• Posts: 1,312
• Joined: 27-December 13

## Re: set operations on sets with more than one of the same member

Posted 08 March 2018 - 12:04 PM

Just a small catch:
Jon's output should be:
Counter({3: 3, 4: 3, 'five': 2, 'six': 1, 2: 3, 1: 3})...the value '2' is only represented 3 times, not 4.

### #7 jon.kiparsky

• Beginner

Reputation: 11069
• Posts: 18,906
• Joined: 19-March 11

## Re: set operations on sets with more than one of the same member

Posted 08 March 2018 - 12:12 PM

Thanks for the correction.

### #8 bobsmith76

Reputation: 9
• Posts: 211
• Joined: 14-February 17

## Re: set operations on sets with more than one of the same member

Posted 08 March 2018 - 02:32 PM

Thanks everyone for their input. This is the solution that I eventually decided to go with:

```    for var, lst in vars.items():
if len(set(lst)) != len(lst):
ct = collections.Counter(lst)
for k, v in dict(ct).items():
if v > 1:
e = 0
for f, prop in enumerate(lst):
if prop == k:
e += 1
prop = prop + str(e)
lst[f] = prop
for var, lst in vars.items():
vars[var] = set(lst)

```

### #9 DK3250

• Pythonian

Reputation: 406
• Posts: 1,312
• Joined: 27-December 13

## Re: set operations on sets with more than one of the same member

Posted 08 March 2018 - 02:50 PM

Please show a full example including 'vars'; apparently, a dictionary containing lists as items...

### #10 jon.kiparsky

• Beginner

Reputation: 11069
• Posts: 18,906
• Joined: 19-March 11

## Re: set operations on sets with more than one of the same member

Posted 08 March 2018 - 03:01 PM

You might also want to express this as a function. This will force you to give it a name, and that name will give me a clue as to what you intend this code to be doing for you, which would be useful.

### #11 bobsmith76

Reputation: 9
• Posts: 211
• Joined: 14-February 17

## Re: set operations on sets with more than one of the same member

Posted 08 March 2018 - 11:04 PM

Well it would be easier to give an example if I could pickle a typical dictionary for this code. Is there some website that allows for pickles to be opened on the website or would each user simply have to download the pickle and specify where the pickle is on their computer?

### #12 jon.kiparsky

• Beginner

Reputation: 11069
• Posts: 18,906
• Joined: 19-March 11

## Re: set operations on sets with more than one of the same member

Posted 08 March 2018 - 11:13 PM

Probably easier from our point of view if it's a dict that you can represent in standard dict notation. The minimal case is what we want, we'd like to be able to see the structure of the thing. If we need a more realistic example later on, we'll burn that bridge when we get to it.

### #13 bobsmith76

Reputation: 9
• Posts: 211
• Joined: 14-February 17

## Re: set operations on sets with more than one of the same member

Posted 08 March 2018 - 11:38 PM

Here's a simplified example. The largest dictionary will have 30 items and some values will have about 3 or 4 of the same member. Vars stands for variables and prop stands for properties.

```def make_vars_different(vars):
vars = {"e": ["Ho", "Ho", "Ss", "To"],
"f": ["Bo", "Bo", "Bs", "Ts", "RDo", "RDp"],
"g": ["Po", "INMo", "Po"]}

for var, lst in vars.items():
if len(set(lst)) != len(lst):
ct = collections.Counter(lst)
for k, v in dict(ct).items():
if v > 1:
e = 0
for f, prop in enumerate(lst):
if prop == k:
e += 1
prop = prop + str(e)
lst[f] = prop
for var, lst in vars.items():
vars[var] = set(lst)

return

```

### #14 DK3250

• Pythonian

Reputation: 406
• Posts: 1,312
• Joined: 27-December 13

## Re: set operations on sets with more than one of the same member

Posted 09 March 2018 - 09:55 AM

Hm, I see some issues here.
1. Line 17-18 are not necessary, you have just ensured that 'lst' is populated by unique members only.
2. I suggest an extra function for increased readability, see the code below.
3. 'vars' is the name of a build-in function, I have changed it to 'varis'

My take:
```import collections

def make_vars_different(varis):

for lst in varis.values():  # only use .values() not .items()
if len(set(lst)) != len(lst):
ct = collections.Counter(lst)
for k, v in dict(ct).items():
if v > 1:
return varis

number = 0
for f, prop in enumerate(lst):
if prop == k:
number += 1
prop = prop + '_' + str(number)  # an underline is added for better eye-catch
lst[f] = prop

varis = {"e": ["Ho", "Ho", "Ss", "To"],
"f": ["Bo", "Bo", "Bs", "Ts", "RDo", "RDp"],
"g": ["Po", "INMo", "Po"]}

v = make_vars_different(varis)

print(v)

```

This post has been edited by DK3250: 09 March 2018 - 10:03 AM

### #15 bobsmith76

Reputation: 9
• Posts: 211
• Joined: 14-February 17

## Re: set operations on sets with more than one of the same member

Posted 09 March 2018 - 12:52 PM

cool. thanks for the input. i'm starting to like sharing my code. about the unncessary lines, i realized they were unnecessary after i posted it. and as for splitting it into two functions, yea, sometimes i get lazy and put them together.