Reputation: 398
I have a list of [i,j] values:
lst = [[1,2],[1,3],[3,4],[4,6]]
#[1,2] means that i=1 and j=2
and add new elenemt [a,b]
, for example [6,1]
, how can I add values to my lst by condition
(add element [a,b]
only if [b,j]
does not exists in a set)
So element [6,1]
should not be added, because [1,2]
and [1,3]
is already in the list
Thanks in advance for any help!
Upvotes: 0
Views: 846
Reputation: 77912
From a readability / maintainability POV I usually prefer to have a custom class handling the invariants instead:
# XXX poor naming but I don't know enough of the context
class Container(object):
def __init__(self, *initvals):
self._values = []
self._keys = set()
for pair in initvals:
self.add(pair)
def add(self, pair):
if pair[1] in self._keys:
raise ValueError("second item of pair '{}' already set".format(pair))
self._keys.add(pair[0])
self._values.append(pair)
def values(self):
# returns a copy so no one accidentally messes
# with internal state
return self._values[:]
c = Container((1,2), (1,3), (3,4), (4,6))
c.add((8, 9))
assert (8, 9) in c.values(), "(8,9) not correctly added"
try:
c.add((6, 1))
except ValueError as e:
#print "got error {} when adding (6,1)".format(e)
pass
else:
assert False, "adding (6, 1) should have raised a ValueError"
print c.values()
Upvotes: 2
Reputation: 82899
You could just iterate the list and check whether for any
of the items (i,j)
in the list, i
is the same as b
in the item (a,b)
you want to add. (At least that's how I understood your condition, but if the condition is slightly different, this should be easy to adapt accordingly.)
def cond_add(lst, item):
a, b = item
if not any(i == b for (i, j) in lst):
lst.append(item)
lst = [[1,2],[1,3],[3,4],[4,6]]
cond_add(lst, [6,1])
cond_add(lst, [6,5])
print(lst)
If you want to add multiple elements, it would pay to create a set
from the first elements, so you can do the check in constant time for each individual item. (You could do the same for adding individual elements, but you'd have to update the set after each item.)
def cond_add_many(lst, items):
first = set(i for (i, j) in lst)
for (a,b) in items:
if b not in first:
lst.append((a,b))
first.add(a)
lst = [[1,2],[1,3],[3,4],[4,6]]
cond_add_many(lst, [[6,1], [6,5], [7,6]])
print(lst)
Afterwards, in both cases, lst
is [[1, 2], [1, 3], [3, 4], [4, 6], (6, 5)]
Upvotes: 2