Χρησιμοποιώντας «in» για να ταιριάζει με ένα χαρακτηριστικό της Python αντικειμένων σε μια σειρά

ψήφοι
39

Δεν θυμάμαι αν ονειρευόμουν ή όχι, αλλά θυμάμαι εκεί είναι μια λειτουργία που επέτρεψε κάτι τέτοιο,

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

Έχω εξετάσει όλα αυτά τα έγγραφα, αλλά κάτι τέτοιο δεν εμπίπτει σε καμία προφανή διατηρητέο ​​κεφαλίδες

Δημοσιεύθηκε 03/08/2008 στις 14:19
πηγή χρήστη
Σε άλλες γλώσσες...                            


8 απαντήσεις

ψήφοι
38

Χρησιμοποιώντας μια λίστα κατανόησης θα οικοδομήσουμε μια προσωρινή λίστα, η οποία θα μπορούσε να φάει όλη τη μνήμη σας, αν η ακολουθία που αναζητήσατε είναι μεγάλη. Ακόμη και αν η ακολουθία δεν είναι μεγάλη, με βάση τον κατάλογο σημαίνει την επανάληψη σε όλη την ακολουθία πριν inθα μπορούσε να ξεκινήσει την αναζήτησή του.

Η προσωρινή λίστα μπορεί να αποφευχθεί με τη χρήση μιας έκφρασης γεννήτριας:

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

Τώρα, όσο obj.id == 12κοντά στην αρχή του bar, η αναζήτηση θα είναι γρήγορη, ακόμη και αν barείναι απείρως μεγάλη.

Όπως προτείνεται @Matt, είναι μια καλή ιδέα να χρησιμοποιήσετε hasattrαν κάποιο από τα αντικείμενα barμπορεί να λείπει ένα idχαρακτηριστικό:

foo = 12
foo in (obj.id for obj in bar if hasattr(obj, 'id'))
Απαντήθηκε 11/09/2008 στις 23:42
πηγή χρήστη

ψήφοι
10

Ψάχνετε για να πάρετε μια λίστα με αντικείμενα που έχουν μια ορισμένη ιδιότητα; Αν ναι, ένας κατάλογος κατανόηση είναι ο σωστός τρόπος για να γίνει αυτό.

result = [obj for obj in listOfObjs if hasattr(obj, 'attributeName')]
Απαντήθηκε 03/08/2008 στις 16:59
πηγή χρήστη

ψήφοι
8

θα μπορούσατε πάντα να γράψω ένα οι ίδιοι:

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

θα συνεργαστεί με κάτι που επαναλαμβάνεται, είναι μια πλειάδα, λίστα, ή ό, τι είναι.

Μου αρέσει python, κάνει τα πράγματα όπως αυτό το πολύ απλό και όχι περισσότερο από μια ταλαιπωρία από ό, τι χρεαστεί, και κατά τη χρήση πράγματα όπως αυτό είναι εξαιρετικά κομψό.

Απαντήθηκε 27/08/2008 στις 21:13
πηγή χρήστη

ψήφοι
4

Η λειτουργία σκέφτεστε πιθανώς operator.attrgettter. Για παράδειγμα, για να πάρετε μια λίστα που περιέχει την τιμή του χαρακτηριστικού «id» κάθε αντικειμένου:

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

Αν θέλετε να ελέγξετε αν η λίστα περιέχει ένα αντικείμενο με ένα == id 12, τότε μια τακτοποιημένη και αποτελεσματική (δηλαδή δεν επαναλάβει όλη τη λίστα χωρίς λόγο) τρόπος για να είναι το κάνουμε:

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

Αν θέλετε να χρησιμοποιήσετε «στο» με attrgetter, ενώ διατηρεί ακόμη τεμπέλης επανάληψη της λίστα:

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

Απαντήθηκε 05/02/2011 στις 09:10
πηγή χρήστη

ψήφοι
4

Όχι, δεν είχαν ονειρευτεί. Η Python έχει ένα πολύ εξαιρετικό σύστημα λίστα κατανόηση που σας επιτρέπει να χειριστείτε τις λίστες αρκετά κομψά, και ανάλογα με το τι ακριβώς θέλετε να πετύχετε, αυτό μπορεί να γίνει με δύο τρόπους. Στην ουσία, αυτό που κάνετε είναι λέει «Για το στοιχείο στη λίστα, αν criteria.matches», και από το ότι μπορείτε να επαναλάβει ακριβώς μέσω των αποτελεσμάτων ή απορρίπτουν τα αποτελέσματα σε μια νέα λίστα.

Πάω να παχνί ένα παράδειγμα από την Dive Into Python εδώ, γιατί είναι πολύ κομψή και είναι πιο έξυπνοι από ό, τι είμαι. Εδώ παίρνουν μια λίστα των αρχείων σε έναν κατάλογο, στη συνέχεια, το φιλτράρισμα της λίστας για όλα τα αρχεία που ταιριάζουν με μια τακτική κριτήρια έκφρασης.

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

Θα μπορούσατε να το κάνετε αυτό χωρίς τις συνήθεις εκφράσεις, για παράδειγμα σας, για οτιδήποτε, όπου η έκφραση σας στο τέλος επιστρέφει ισχύει και για έναν αγώνα. Υπάρχουν και άλλες επιλογές, όπως τη χρήση της λειτουργίας του φίλτρου (), αλλά αν επρόκειτο να επιλέξετε, θα πήγαινα με αυτό.

Eric Sipple

Απαντήθηκε 03/08/2008 στις 15:30
πηγή χρήστη

ψήφοι
3

Αν σχεδιάζετε να ψάχνουν κάτι εξ αποστάσεως αξιοπρεπές μέγεθος, το καλύτερο στοίχημά σας θα είναι να χρησιμοποιήσετε ένα λεξικό ή ένα σύνολο. Σε αντίθετη περίπτωση, πρέπει βασικά να επαναλαμβάνεται σε κάθε στοιχείο του iterator μέχρι να φτάσετε σε αυτήν που θέλετε.

Εάν αυτό δεν είναι απαραίτητα ευαίσθητα απόδοση κώδικα, τότε η λίστα τρόπος κατανόησης θα πρέπει να εργαστεί. Αλλά σημειώστε ότι είναι αρκετά αναποτελεσματική γιατί πηγαίνει πέρα ​​από κάθε στοιχείο του iterator και στη συνέχεια πηγαίνει πίσω πάνω ξανά μέχρι να βρει αυτό που θέλει.

Να θυμάστε, η Python έχει ένα από τα πιο αποδοτικών αλγορίθμων κατακερματισμού γύρω. Χρησιμοποιήστε το για να σας πλεονέκτημα.

Απαντήθηκε 27/08/2008 στις 21:30
πηγή χρήστη

ψήφοι
3

Αυτό που σκεφτόμουν μπορεί να επιτευχθεί με τη χρήση λίστας Η κατανόηση, αλλά σκέφτηκα ότι υπήρχε μια λειτουργία που το έκανε αυτό σε μια ελαφρώς πιο τακτοποιημένη τρόπο.

δηλαδή «γραμμή» είναι ένας κατάλογος των αντικειμένων, τα οποία έχουν το χαρακτηριστικό «id»

Το μυθικό λειτουργικό τρόπο:

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

Ο τρόπος με λίστα κατανόηση:

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

Εκ των υστέρων ο τρόπος με λίστα κατανόηση είναι αρκετά καλό ούτως ή άλλως.

Απαντήθηκε 03/08/2008 στις 17:13
πηγή χρήστη

ψήφοι
-1

Νομίζω:

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

Είναι αυτό που σκέφτεστε. Όταν προσπαθείτε να δείτε αν ένα συγκεκριμένο κλειδί υπάρχει μέσα σε ένα λεξικό σε python (έκδοση πύθωνα του πίνακα κατακερματισμού) υπάρχουν δύο τρόποι για να ελέγξετε. Πρώτη είναι η has_key()μέθοδος που επισυνάπτεται στο λεξικό και δεύτερο είναι το παράδειγμα που δίνεται παραπάνω. Θα επιστρέψει μια boolean τιμή.

Αυτό θα πρέπει να απαντήσω στην ερώτησή σας.

Και τώρα λίγο εκτός θέματος για να συνδέσει αυτό με τη λίστα κατανόηση απάντηση που δόθηκε προηγουμένως (για λίγο περισσότερη σαφήνεια). Λίστα Η κατανόηση κατασκευάσει μια λίστα από μια βασική για βρόχο με τροποποιητές. Ως παράδειγμα (να διευκρινιστεί ελαφρώς), έναν τρόπο για να χρησιμοποιήσετε το in dictκατασκεύασμα γλώσσα σε μια λίστα με κατανόηση :

Ας υποθέσουμε ότι έχετε ένα δισδιάστατο λεξικό fooκαι θέλετε μόνο τη δεύτερη διάσταση λεξικά τα οποία περιέχουν το κλειδί bar. Ένα σχετικά απλό τρόπο για να γίνει αυτό θα ήταν να χρησιμοποιήσετε μια λίστα με κατανόηση με όρους ως εξής:

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

Σημειώστε το if bar in valueστο τέλος της δήλωσης **, πρόκειται για μια ρήτρα τροποποίησης που αφηγείται την λίστα κατανόηση για να κρατήσει μόνο τα ζεύγη κλειδιών-τιμών που πληρούν την προϋπόθεση. ** Σε αυτή την περίπτωση bazείναι ένα νέο λεξικό που περιέχει μόνο τα λεξικά από την foo τα οποία περιέχουν bar (Ας ελπίσουμε ότι δεν έχασε τίποτα σε αυτό το παράδειγμα κώδικα ... ίσως χρειαστεί να ρίξετε μια ματιά στη λίστα ομάδας τεκμηρίωσης κατανόηση βρίσκονται σε docs.python.org σεμινάρια και secnetix.de , και οι δύο περιοχές είναι καλές αναφορές, αν έχετε ερωτήσεις στο μέλλον.).

Απαντήθηκε 03/08/2008 στις 16:47
πηγή χρήστη

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