Gebruik 'in' een kenmerk Python objecten passen in een array

stemmen
39

Ik weet niet meer of ik niet droomde of maar ik schijn er te herinneren dat een functie die iets als toegestaan,

foo in iter_attr(array of python objects, attribute name)

Ik heb gekeken over de documenten, maar dit soort dingen valt niet onder voor de hand liggende beursgenoteerde headers vallen

De vraag is gesteld op 03/08/2008 om 14:19
bron van user
In andere talen...                            


8 antwoorden

stemmen
4

Nee, je niet droomt. Python heeft een mooie uitstekende lijstcomprehensie systeem waarmee u lijsten manipuleren vrij elegant, en afhankelijk van wat u precies wilt bereiken, kan dit een aantal manieren worden gedaan. In wezen, wat je doet is zeggen "Voor post in lijst als criteria.matches", en vanaf dat je kunt gewoon doorlopen van de resultaten of dumpen van de resultaten in een nieuwe lijst.

Ik ga naar een voorbeeld uit de wieg Dive Into Python hier, want het is erg elegant en ze zijn slimmer dan ik. Hier ze krijgen een lijst met bestanden in een map, dan is het filteren van de lijst voor alle bestanden die voldoen aan een reguliere expressie criteria.

    files = os.listdir(path)                               
    test = re.compile("test\.py$", re.IGNORECASE)          
    files = [f for f in files if test.search(f)]

U kunt dit doen zonder reguliere expressies, voor uw voorbeeld, voor iets waar uw uitdrukking aan het einde geeft true voor een wedstrijd. Er zijn andere opties zoals met de functie filter (), maar als ik zou gaan om uit te kiezen, zou ik ga met dit.

Eric Sipple

antwoordde op 03/08/2008 om 15:30
bron van user

stemmen
-1

I denk:

#!/bin/python
bar in dict(Foo)

Is wat je denkt. Wanneer het proberen om te zien of een bepaalde toets bestaat in een woordenboek in python (versie python's van een hash tabel) zijn er twee manieren om te controleren. Ten eerste is de has_key()methode bevestigd aan het woordenboek en tweede wordt het hierboven gegeven voorbeeld. Het zal een boolean waarde terug te keren.

Dat moet je vraag te beantwoorden.

En nu een beetje off topic om dit te binden in de lijst begrip antwoord eerder gegeven (voor een beetje meer duidelijkheid). Lijstcomprehensies de bouw van een lijst van een basis voor de lus met modifiers. Als voorbeeld (iets te verduidelijken), een manier om het te gebruiken in dicttaal construct in een lijst begrip :

Stel je hebt een tweedimensionale woordenboek fooen u wilt dat alleen de tweede dimensie woordenboeken die de sleutel bevatten bar. Een relatief eenvoudige manier om dit te doen zou zijn om een te gebruiken lijstcomprehensie als volgt met een voorwaardelijke:

#!/bin/python
baz = dict([(key, value) for key, value in foo if bar in value])

Let op de if bar in valueaan het eind van de verklaring **, dit is een modificerend bevatten die in de vertelt lijst begrip om alleen die bewaren key-waarde paren die voldoen aan de voorwaardelijke. ** In dit geval bazis een nieuw woordenboek, die alleen de woordenboeken van foo bevat welke bar bevatten (Hopelijk heb ik niets in die code bijvoorbeeld missen ... je kan hebben om een kijkje op de lijst begrip documentatie in te nemen docs.python.org tutorials en secnetix.de , beide sites zijn goede referenties als u vragen in de toekomst.).

antwoordde op 03/08/2008 om 16:47
bron van user

stemmen
10

Bent u op zoek naar een lijst van objecten die een bepaalde eigenschap hebben te krijgen? Als dat zo is, een lijst begrip is de juiste manier om dit te doen.

result = [obj for obj in listOfObjs if hasattr(obj, 'attributeName')]
antwoordde op 03/08/2008 om 16:59
bron van user

stemmen
3

Wat ik dacht aan kan worden bereikt met behulp Lijstcomprehensies, maar ik dacht dat er een functie die dit in een iets nettere manier deed.

dat wil zeggen 'bar' is een lijst met objecten, die allemaal het kenmerk 'id'

De mythische functionele manier:

foo = 12
foo in iter_attr(bar, 'id')

De lijstcomprehensie manier:

foo = 12
foo in [obj.id for obj in bar]

Achteraf de lijst begrip manier is het toch vrij netjes.

antwoordde op 03/08/2008 om 17:13
bron van user

stemmen
8

je kon altijd een schrijven jezelf:

def iterattr(iterator, attributename):
    for obj in iterator:
        yield getattr(obj, attributename)

zal werken met iets dat herhaalt, of het nu een tupel, lijst, of wat dan ook.

Ik hou van python, het maakt dingen zoals dit zeer eenvoudig en niet meer van een gedoe dan benodigde, en in gebruik genomen dingen zoals dit is enorm elegant.

antwoordde op 27/08/2008 om 21:13
bron van user

stemmen
3

Als u van plan om het even wat van op afstand behoorlijke omvang zoeken, is uw beste weddenschap gaat worden naar een woordenboek of een set te gebruiken. Zo niet, je in principe moet doorlopen elk element van de iterator tot je degene die je wilt.

Als dit is niet per se de prestaties gevoelig code, dan is de lijst begrip manier zou moeten werken. Maar let op dat het vrij inefficiënt, omdat het gaat over elk element van de iterator en gaat dan terug over het weer, totdat het vindt wat hij wil.

Vergeet niet, python heeft een van de meest efficiënte hashing algoritmen rond. Gebruik het om uw voordeel.

antwoordde op 27/08/2008 om 21:30
bron van user

stemmen
38

Met behulp van een lijst begrip zou een tijdelijke lijst, die al uw geheugen kon eten indien de sequentie wordt gezocht is groot te bouwen. Zelfs als de volgorde is niet groot, de bouw van de lijst betekent itereren over het geheel van de reeks alvorens inkon zijn zoektocht te starten.

De tijdelijke lijst kan worden voorkomen door een generator uitdrukking:

foo = 12
foo in (obj.id for obj in bar)

Nu, zolang obj.id == 12in de buurt van het begin van bar, wordt de zoekactie snel zijn, ook al baris oneindig lang.

Zoals @Matt gesuggereerd, is het een goed idee om te gebruiken hasattrals een van de objecten in barmag ontbreken een idattribuut:

foo = 12
foo in (obj.id for obj in bar if hasattr(obj, 'id'))
antwoordde op 11/09/2008 om 23:42
bron van user

stemmen
4

De functie die u van denken is waarschijnlijk operator.attrgettter. Als u bijvoorbeeld een lijst die de waarde van de "id" attribuut elk object bevat krijgen:

import operator
ids = map(operator.attrgetter("id"), bar)

Als u wilt controleren of de lijst bevat een object met een id == 12, dan is een nette en efficiënte (dwz niet onnodig herhalen de hele lijst) manier om het te doen:

any(obj.id == 12 for obj in bar)

Als u wilt gebruiken 'in' met attrgetter, terwijl nog steeds lui iteratie van de lijst met behoud van:

import operator,itertools
foo = 12
foo in itertools.imap(operator.attrgetter("id"), bar)

antwoordde op 05/02/2011 om 09:10
bron van user

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more