Hello I've been coding for a couple of months now and know the basics, but I'm having a set membership problem for which I can't find a solution.
I have a list of lists of pairs of integers, and I want to remove the list that have the "a" integer in them. I thought using sets was the easiest way. Bellow is the code:
## This is the item to test against.
a = set([3])
## This is the list to test.
groups = [[3, 2], [3, 4], [1, 2], [5, 4], [4, 3]]
## This is a list that will contain the lists present
## in groups which do not contain "a"
groups_no_a = []
for group in groups:
group = set(group)
if a in group:
groups_no_a.append(group)
## I thought the problem had something to do with
## clearing the variable so I put this in,
## but to no remedy.
group.clear()
print groups_no_a
I had also tried using s.issubset(t)
until I realized that this tested if every element in s
in t
.
Thank you!
You want to test if there is no intersection:
if not a & group:
or
if not a.intersection(group):
or, inversely, that the sets are disjoint:
if a.isdisjoint(group):
The method forms take any iterable, you don't even have to turn group
into a set for that. The following one-liner would work too:
groups_no_a = [group for group in groups if a.isdisjoint(group)]
Demo:
>>> a = set([3])
>>> groups = [[3, 2], [3, 4], [1, 2], [5, 4], [4, 3]]
>>> [group for group in groups if a.isdisjoint(group)]
[[1, 2], [5, 4]]
If all you are testing for is one element, then it could be that creating sets is going to cost more in performance than what you gain in testing for membership, and just doing:
3 not in group
where group
is a short list.
You can use the timeit
module to compare pieces of Python code to see what works best for your specific typical list sizes.
Maybe you could use List Comprehension:
a = 3
groups = [[3, 2], [3, 4], [1, 2], [5, 4], [4, 3]]
print [x for x in groups if a not in x]
Edit based on a comment:
Well to those curious, what I want to do is; I have a list like the following: [ [error, [ [group_item_1, group_item_2], [...], [...], [...] ] ], [more like this previous], [...] ], and I want to get the item with least error and that doesn't have "a" in group_item_1 or group_item_2. The lists are already sorted by error. I sorta almost go it :D
This should do the trick:
from itertools import chain, iterfilter
def flatten(listOfLists):
"Flatten one level of nesting"
return chain.from_iterable(listOfLists)
errors_list = [ ['error0', [ [30, 2], [3, 4], [1, 2], [5, 4], [4, 3] ] ], ['error1', [ [31, 2], [3, 4], [1, 2], [5, 4], [4, 3] ] ] ]
a = 30
result = next(ifilter(lambda err: a not in flatten(err[1]), reversed(errors_list)), None)
print result #finds error1 as it has no 30 on its list
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With