Simple - looking for a way to do an element exists check..

R

rh0dium

Hi all,

I have a simple list to which I want to append another tuple if
element 0 is not found anywhere in the list.

element = ('/smsc/chp/aztec/padlib/5VT.Cat',
'/smsc/chp/aztec/padlib',
'5VT.Cat', (33060))

element1 = ('/smsc/chp/aztec/padlib/5VT.Cat2',
'/smsc/chp/aztec/padlib',
'5VT.Cat2', (33060))

a = [ ('/smsc/chp/aztec/padlib/5VT.Cat',
'/smsc/chp/aztec/padlib',
'5VT.Cat', (33060)),
('/smsc/chp/aztec/padlib/padlib.TopCat%',
'/smsc/chp/aztec/padlib',
'padlib.TopCat%', (33204)),
('/smsc/chp/aztec/padlib/Regulators.Cat%',
'/smsc/chp/aztec/padlib',
'Regulators.Cat%', (33204))]

So my code would look something like this.

found = False
for item in a:
if item[0] == element[0]
found = True
break
if not found:
a.append(element)

But this is just ugly - Is there a simpler way to interate over all
items in a without using a found flag?

Thanks
 
P

Paul McGuire

found = False
for item in a:
  if item[0] == element[0]
    found = True
    break
if not found:
  a.append(element)

But this is just ugly - Is there a simpler way to interate over all
items in a without using a found flag?

Thanks


for item in a:
if item[0] == element[0]
break
else: # only called if we never 'break' out of the for loop
a.append(element)


But what about a dict?

adict = dict((elem[0],elem) for elem in a)

if item[0] not in adict:
adict[item[0]] = item

# need the final list?
a = adict.values()

No list searching, and will scale well if a gets real long.

-- Paul
 
P

Paul McGuire

Hi all,

I have a simple list to which I want to append another tuple if
element 0 is not found anywhere in the list.

element =  ('/smsc/chp/aztec/padlib/5VT.Cat',
  '/smsc/chp/aztec/padlib',
  '5VT.Cat', (33060))

element1 =  ('/smsc/chp/aztec/padlib/5VT.Cat2',
  '/smsc/chp/aztec/padlib',
  '5VT.Cat2', (33060))

a =  [ ('/smsc/chp/aztec/padlib/5VT.Cat',
  '/smsc/chp/aztec/padlib',
  '5VT.Cat', (33060)),
 ('/smsc/chp/aztec/padlib/padlib.TopCat%',
  '/smsc/chp/aztec/padlib',
  'padlib.TopCat%', (33204)),
 ('/smsc/chp/aztec/padlib/Regulators.Cat%',
  '/smsc/chp/aztec/padlib',
  'Regulators.Cat%', (33204))]

So my code would look something like this.

found = False
for item in a:
  if item[0] == element[0]
    found = True
    break
if not found:
  a.append(element)

But this is just ugly - Is there a simpler way to interate over all
items in a without using a found flag?

Thanks

Well, that's what I get for typing before thinking...

If the remaining items in each element tuple are the same for any
given element[0], then just use a set.

aset = set(a)
for element in list_of_new_element_tuples:
aset.add(element)

-- Paul
 
J

Jason

Hi all,

I have a simple list to which I want to append another tuple if
element 0 is not found anywhere in the list.

element = ('/smsc/chp/aztec/padlib/5VT.Cat',
'/smsc/chp/aztec/padlib',
'5VT.Cat', (33060))

element1 = ('/smsc/chp/aztec/padlib/5VT.Cat2',
'/smsc/chp/aztec/padlib',
'5VT.Cat2', (33060))

a = [ ('/smsc/chp/aztec/padlib/5VT.Cat',
'/smsc/chp/aztec/padlib',
'5VT.Cat', (33060)),
('/smsc/chp/aztec/padlib/padlib.TopCat%',
'/smsc/chp/aztec/padlib',
'padlib.TopCat%', (33204)),
('/smsc/chp/aztec/padlib/Regulators.Cat%',
'/smsc/chp/aztec/padlib',
'Regulators.Cat%', (33204))]

So my code would look something like this.

found = False
for item in a:
if item[0] == element[0]
found = True
break
if not found:
a.append(element)

But this is just ugly - Is there a simpler way to interate over all
items in a without using a found flag?

Thanks

How-about using a generator expression and Python's built-in "in"
operator:
.... if newData[0] not in (x[0] for x in myData):
.... myData.append( newData )
....
l = []
example( l, ('a', 'apple', 'aviary') )
l [('a', 'apple', 'aviary')]
example( l, ('s', 'spam', 'silly') )
l [('a', 'apple', 'aviary'), ('s', 'spam', 'silly')]
example( l, ('s', 'suck-tastic') )
l [('a', 'apple', 'aviary'), ('s', 'spam', 'silly')]
 
P

Paul Rubin

rh0dium said:
found = False
for item in a:
if item[0] == element[0]
found = True
break
if not found:
a.append(element)

But this is just ugly - Is there a simpler way to interate over all
items in a without using a found flag?

Untested and I'm not sure I understand the question completely, but
try:

if any(x==element[0] for x in a):
a.append(element)
 
P

Paul McGuire

Paul Rubin said:
    if any(x==element[0] for x in a):
      a.append(element)

Should say:

     if any(x[0]==element[0] for x in a):
        a.append(element)

I think you have this backwards. Should be:

if not any(x[0]==element[0] for x in a):
a.append(element)

or

if all(x[0]!=element[0] for x in a):
a.append(element)

-- Paul
 
P

Paul Rubin

Paul McGuire said:
I think you have this backwards. Should be:

if not any(x[0]==element[0] for x in a):
a.append(element)

I think you are right, it was too early for me to be reading code when
I posted that ;-)
 
P

Paul McGuire

Paul McGuire said:
I think you have this backwards.  Should be:
     if not any(x[0]==element[0] for x in a):
        a.append(element)

I think you are right, it was too early for me to be reading code when
I posted that ;-)

I'm still getting used to 'any' and 'all' as new Python built-ins -
but they'll do the short-circuiting as well as a for-loop-with-break.
But I think a set- or dict-based solution will still surpass a list-
based one for the OP.

-- Paul
 
P

Paul Rubin

Paul McGuire said:
I'm still getting used to 'any' and 'all' as new Python built-ins -
but they'll do the short-circuiting as well as a for-loop-with-break.
But I think a set- or dict-based solution will still surpass a list-
based one for the OP.

I guess I don't understand sufficiently well what the OP is trying to
do. If it's just a matter of checking for and then appending one
record, then using "any" looks like the most straightforward. If the
idea is to collect one representative of each value of element[0], and
if the value is hashable, then yes, a set or dict is the best way to
do it.
 
P

Paul Hankin

Paul Rubin said:
    if any(x==element[0] for x in a):
      a.append(element)
Should say:
     if any(x[0]==element[0] for x in a):
        a.append(element)

I think you have this backwards.  Should be:

     if not any(x[0]==element[0] for x in a):
        a.append(element)

IMO Jason's solution of testing containment in a generator is better
(more readable).
if element[0] not in (x[0] for x in a):
a.append(element)
 
T

thebjorn

if any(x==element[0] for x in a):
a.append(element)
Should say:
if any(x[0]==element[0] for x in a):
a.append(element)
I think you have this backwards. Should be:
if not any(x[0]==element[0] for x in a):
a.append(element)

IMO Jason's solution of testing containment in a generator is better
(more readable).
if element[0] not in (x[0] for x in a):
a.append(element)

It may be more readable (although that's debatable), but it always
traverses the entire list.

If the list is short I'd use either the traditional "for/else" or the
newer "if all(...)":

if all(x[0] != element[0] for x in a):
a.append(element)

which allows for short-circuit evaluation -- I generally try to stay
away from negating any() and all() because the logic often gets
convoluted.

If the lists are long enough to care, either rewrite use a set-based
solution if the items are hashable, or keep the elements sorted and
rewrite to use the bisect module if the elements can be ordered.

-- bjorn
 
P

Paul Rubin

thebjorn said:
If the lists are long enough to care, either rewrite use a set-based
solution if the items are hashable, or keep the elements sorted and
rewrite to use the bisect module if the elements can be ordered.

Well, you want a tree data structure to have fast insertions to
remember what items have already been seen. There's been a bunch
of proposals for an ordered dict type that works like this.

Some day...
 
T

thebjorn

Well, you want a tree data structure to have fast insertions to
remember what items have already been seen. There's been a bunch
of proposals for an ordered dict type that works like this.

Some day...

Amen! .. *sigh*...
 
M

Marc 'BlackJack' Rintsch

IMO Jason's solution of testing containment in a generator is better
(more readable).
if element[0] not in (x[0] for x in a):
a.append(element)

It may be more readable (although that's debatable), but it always
traverses the entire list.

The ``not in`` stops if the element is found.

Ciao,
Marc 'BlackJack' Rintsch
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top