[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

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

rh0dium

2/22/2008 5:20:00 PM

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


17 Answers

Paul McGuire

2/22/2008 5:28:00 PM

0

On Feb 22, 11:20 am, rh0dium <steven.kl...@gmail.com> wrote:
>
> 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

Paul McGuire

2/22/2008 5:32:00 PM

0

On Feb 22, 11:20 am, rh0dium <steven.kl...@gmail.com> wrote:
> 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

Jason

2/22/2008 5:36:00 PM

0

On Feb 22, 10:20 am, rh0dium <steven.kl...@gmail.com> wrote:
> 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:

>>> def example(myData, newData):
.... 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')]
>>>

Paul Rubin

2/22/2008 6:50:00 PM

0

rh0dium <steven.klass@gmail.com> writes:
> 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)

Paul Rubin

2/22/2008 6:54:00 PM

0

Paul Rubin <http://phr.cx@NOSPAM.i... writes:
> 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)

Paul McGuire

2/22/2008 7:01:00 PM

0

On Feb 22, 12:54 pm, Paul Rubin <http://phr...@NOSPAM.invalid> wrote:
> Paul Rubin <http://phr...@NOSPAM.invalid> writes:
> >     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

Paul Rubin

2/22/2008 9:38:00 PM

0

Paul McGuire <ptmcg@austin.rr.com> writes:
> 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 ;-)

Paul McGuire

2/22/2008 9:51:00 PM

0

On Feb 22, 3:38 pm, Paul Rubin <http://phr...@NOSPAM.invalid> wrote:
> Paul McGuire <pt...@austin.rr.com> writes:
> > 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

Paul Rubin

2/22/2008 10:04:00 PM

0

Paul McGuire <ptmcg@austin.rr.com> writes:
> 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.

Boris Ozegovic

2/23/2008 2:36:00 PM

0

Paul Rubin wrote:

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

How come this list comprehension isn't in [] brackets?