DIMITRISG Δημοσ. 7 Μαΐου 2019 Δημοσ. 7 Μαΐου 2019 Γεια και χαρά μήπως γνωρίζει κανείς μια βιβλιοθήκη που να κάνει την παρακάτω δουλειά κάπως πιο αυτόματα και πιο σωστά (pythonic) γιατί μου φαίνεται κακάσχημο αυτό που έγγραψα. θέλω να φιλτράρω τα αντικείμενα ενός iterator και όταν το 1 έχει 0 δεξιά και αριστερά να γίνεται 0. Η numpy κάνει κάτι τέτοιο; (δεν ξέρω και πως να το ψάξω στο διαδίκτυο) >>> a=[0,0,0,1,0,1,0,1,1,1,0,1] >>> a [0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1] [0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1] >>> b = a[:] >>> for i in range(1, len(b)): if i == len(b) - 1: break if b[i] == 1 and b[i - 1] == 0 and b[i + 1] == 0: a[i] = 0 >>> a [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1] >>> b [0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1] >>>
Heyho Δημοσ. 7 Μαΐου 2019 Δημοσ. 7 Μαΐου 2019 (επεξεργασμένο) a[0:1] + [int(any([a[i - 1], a[i + 1]])) * a[i] for i in range(1, len(a) - 1)] + a[-1:] Και δεν φιλτάρεις iterator αλλά iterable. Ο iterator δεν φιλτράρεται. Και δεν φιλτράρεις αλλά κάνεις modify. Εφόσον έχουν το ίδιο μήκος οι λίστες, δεν είναι filtering. Επεξ/σία 7 Μαΐου 2019 από Heyho
stefanos90_K Δημοσ. 7 Μαΐου 2019 Δημοσ. 7 Μαΐου 2019 (επεξεργασμένο) a = [0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1] print 'Before: ', a for indx, val in enumerate(a): if val: # Check for 1 try: if (a[indx - 1] == 0) and a[indx + 1] == 0: a[indx] = 0 except IndexError: # Avoid out of index pass print 'After: ', a Μπορείς να γράψεις πολύπλοκα και απλά. Σε κάτι απλό σε σύνταξη μπορείς να κάνεις κάτι σαν το παραπάνω. Αλλά γενικά αυτό που χρειάζεσαι είναι -Βρες τα index που έχουν 1 -Ελέγχεις πριν και μετά αλλά πρόσεξε μη βγεις έξω από την λίστα σου -Επεξεργάζεσαι οτι χρειάζεται. Επεξ/σία 7 Μαΐου 2019 από stefanos90_K
albNik Δημοσ. 7 Μαΐου 2019 Δημοσ. 7 Μαΐου 2019 (επεξεργασμένο) Αν το μετατρεψεις σε string κανε κατι σαν replace '010' με '000'. Iσως χρεαστει να κανεις replace μεχρι που να μην αλλαζει while(newStr=oldΣτρ.replace('010' , '000')) Επεξ/σία 7 Μαΐου 2019 από albNik
Heyho Δημοσ. 7 Μαΐου 2019 Δημοσ. 7 Μαΐου 2019 2 ώρες πριν, DIMITRISG είπε πιο αυτόματα και πιο σωστά (pythonic) γιατί μου φαίνεται κακάσχημο αυτό που έγγραψα. 34 λεπτά πριν, stefanos90_K είπε a = [0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1] print 'Before: ', a for indx, val in enumerate(a): if val: # Check for 1 try: if (a[indx - 1] == 0) and a[indx + 1] == 0: a[indx] = 0 except IndexError: # Avoid out of index pass print 'After: ', a Μπορείς να γράψεις πολύπλοκα και απλά. Σε κάτι απλό σε σύνταξη μπορείς να κάνεις κάτι σαν το παραπάνω. Αλλά γενικά αυτό που χρειάζεσαι είναι -Βρες τα index που έχουν 1 -Ελέγχεις πριν και μετά αλλά πρόσεξε μη βγεις έξω από την λίστα σου -Επεξεργάζεσαι οτι χρειάζεται. 7 λεπτά πριν, albNik είπε Αν το μετατρεψεις σε string κανε κατι σαν replace '010' με '000'. Iσως χρεαστει να κανεις replace μεχρι που να μην αλλαζει while(newStr=oldΣτρ.replace('010' , '000')) LOL!!!! Δεν θέλω να φανταστώ τι θα έβλεπαν τα ματάκια μου εάν δεν έγραφε "πιο αυτόματα και πιο σωστά" ο ΟΡ!!! 36 λεπτά πριν, stefanos90_K είπε -Ελέγχεις πριν και μετά αλλά πρόσεξε μη βγεις έξω από την λίστα σου Εάν κάνεις loop πάνω σε λίστα και καταφέρεις να βγεις εκτός λίστας, σταμάτα να γράφεις σε Python. Έλεος δηλαδή! Υ.Γ. Python 2.X το 2019;
albNik Δημοσ. 7 Μαΐου 2019 Δημοσ. 7 Μαΐου 2019 6 λεπτά πριν, Heyho είπε LOL!!!! Δεν θέλω να φανταστώ τι θα έβλεπαν τα ματάκια μου εάν δεν έγραφε "πιο αυτόματα και πιο σωστά" ο ΟΡ!!! Αυτο που ειπα ειναι η ιδεα του replace σε σχεση με το iteration ελεγχοντας τους δεικτες a, i-1, , i+1 κλπ. Θα μπορουσε να το υποστηρίζει και ο πινακας (δεν ξερω python) κατι τετοιο array.replace([1,2,3], [4,5,6])
Heyho Δημοσ. 7 Μαΐου 2019 Δημοσ. 7 Μαΐου 2019 (επεξεργασμένο) 1 λεπτό πριν, albNik είπε Αυτο που ειπα ειναι η ιδεα του replace σε σχεση με το iteration ελεγχοντας τους δεικτες a, i-1, , i+1 κλπ. Θα μπορουσε να το υποστηρίζει και ο πινακας (δεν ξερω python) κατι τετοιο array.replace([1,2,3], [4,5,6]) Εάν δεν ξέρεις Python , τότε γιατί απαντάς; Χώρια από το εάν ξέρεις ή όχι, το int σε str και μετά πάλι σε int για να κάνεις replace/modify, είναι όχι απλά λάθος... είναι τρελό μαργαριτάρι. Για να το προτείνεις αυτό, δεν πρέπει να ξέρεις γενικά και όχι μόνο Python. Επεξ/σία 7 Μαΐου 2019 από Heyho
MitsarasAth Δημοσ. 7 Μαΐου 2019 Δημοσ. 7 Μαΐου 2019 48 λεπτά πριν, Heyho είπε Εάν δεν ξέρεις Python , τότε γιατί απαντάς; Χώρια από το εάν ξέρεις ή όχι, το int σε str και μετά πάλι σε int για να κάνεις replace/modify, είναι όχι απλά λάθος... είναι τρελό μαργαριτάρι. Για να το προτείνεις αυτό, δεν πρέπει να ξέρεις γενικά και όχι μόνο Python. καλως τον κυριο clean code και best practice
albNik Δημοσ. 7 Μαΐου 2019 Δημοσ. 7 Μαΐου 2019 1 ώρα πριν, Heyho είπε Εάν δεν ξέρεις Python , τότε γιατί απαντάς; Χώρια από το εάν ξέρεις ή όχι, το int σε str και μετά πάλι σε int για να κάνεις replace/modify, είναι όχι απλά λάθος... είναι τρελό μαργαριτάρι. Για να το προτείνεις αυτό, δεν πρέπει να ξέρεις γενικά και όχι μόνο Python. Τα 0, 1 θα μπορουσαν να ειναι οτιδήποτε. int , bool , string , char...εσυ κόλλησες στη μετατροπή.
pmav99 Δημοσ. 7 Μαΐου 2019 Δημοσ. 7 Μαΐου 2019 Μια λύση με numpy (χωρίς loop) 1. Το πρώτο και το τελευταίο στοιχείο του πίνακα δεν μπορούν να αλλάξουν για αυτό και με ασφάλεια μπορούμε να τα αφαιρέσουμε. import numpy as np a = np.array([0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1]) b = a[1:-1].copy() b # array([0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0]) 2. Για να αποφύγουμε να κάνουμε loop, μπορούμε να χρησιμοποιήσουμε την np.roll η οποία μας δίνει ένα νέο πίνακα με μετατοπισμένα indices. Συνδυάζοντας την με την stack παίρνουμε ένα 3xN πίνακα οι στήλες του οποίου είναι το slice a[i-1:i+1]: c = np.stack( ( np.roll(b, 1), b, np.roll(b, -1) ), axis=0 ) c # array([[0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1], # [0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0], # [0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0]]) 3. To μόνο που μένει να κάνουμε τώρα είναι να βρούμε τα indices από τις στήλες που έχουν την τιμή [0, 1, 0]: np.all((c.T == (0, 1, 0)).T, axis=0) # array([False, False, True, False, True, False, False, False, False, False, True, False]) 4. Στο βήμα 1 αφαιρέσαμε το 1ο και το τελευταίο στοιχείο του πίνακα. Ας τα προσθέσουμε: indices = np.concatenate( ( np.array([False]), np.all((c.T == (0, 1, 0)).T, axis=0), np.array([False]), ), axis=0, ) indices # array([False, False, False, True, False, True, False, False, False, False, False, True, False, False]) 5. Tέλος ας αντικαταστήσουμε τις τιμές: final = a.copy() final[indices] = 0 final # array([0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1]) Τα copy() δεν χρειάζονται αλλά αν δεν τα βάλουμε τα assignments θα γίνουν inplace και δεν θα μπορούμε να ελέγξουμε τις τιμές των ενδιάμεσων πινάκων στο τέλος.
cvb~ Δημοσ. 7 Μαΐου 2019 Δημοσ. 7 Μαΐου 2019 (επεξεργασμένο) Καλησπέρα. Διαβάζοντας το νήμα και με αφορμή το ζητούμενο του θέματος έγραψα μια μίκρη εκδοχή, στη C όμως. Ίσως νά χει και λάθη, οπότε πείτε το αν δείτε τίποτα. Ο κώδικας και ένα screenshot απ' το πρόγραμμα είναι: /* Θέλουμε όπου υπάρχει 1 μέσα στον πίνακα και έχει δεξια και αριστερά του 0, τότε το 1 να γίνεται κι' αυτό 0. */ #include <stdio.h> /* Ο πίνακας μας με τα 0 και τα 1 */ int arr[] = { 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1 }; /* Με αυτή τη συνάρτηση εκτυπώνουμε τις τιμές του πίνακα */ void print_arr(void); int main(void) { int i; print_arr(); /* Εδώ κοιτάμε ο βρόχος να μη πιάνει τα άκρα και να εξετάζει κάθε τιμή άν είναι 1, και κάθε προηγούμενη και επόμενη αν είναι 0. Τότε τα 1 γίνονται 0. */ for(i = 0; i < 12; i++) { if((i > 0) && (i < 11) && i >(arr[i] == 1) && (arr[i-1] == 0) && (arr[i+1] == 0)) { arr[i] = 0; } } print_arr(); return 0; } void print_arr(void) { int i; for(i = 0; i < 12; i++) { printf("%d ", arr[i]); } printf("\n"); } Επεξ/σία 7 Μαΐου 2019 από cvb~
pmav99 Δημοσ. 7 Μαΐου 2019 Δημοσ. 7 Μαΐου 2019 Και λίγο πιο concisely μπορεί να γίνει έτσι: import numpy as np a = np.array([0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1]) c = np.stack((np.roll(a, 1), a, np.roll(a, -1)), axis=0) indices = np.pad( array=np.all((c.T == (0, 1, 0)).T, axis=0)[1:-1], pad_width=1, mode="constant", constant_values=False, ) a[indices] = 0
Heyho Δημοσ. 7 Μαΐου 2019 Δημοσ. 7 Μαΐου 2019 (επεξεργασμένο) Εάν το πρόβλημα είναι η λέξη "for" (γιατί και το "all" με επανάληψη γίνεται), τότε μπορεί κανείς να το κάνει κάπως έτσι: def filter_my_list(my_list): return lambda x: int(any([my_list[x - 1], my_list[x + 1]]) * my_list[x]) a = [0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1] b = a[0:1] + list(map(filter_my_list(a), range(1, len(a) - 1))) + a[-1:] Επεξ/σία 7 Μαΐου 2019 από Heyho
pmav99 Δημοσ. 7 Μαΐου 2019 Δημοσ. 7 Μαΐου 2019 (επεξεργασμένο) 26 minutes ago, Heyho said: Εάν το πρόβλημα είναι η λέξη "for" Το «πρόβλημα» προφανώς δεν είναι το keyword "for" αλλά το performance. Από κάποιο Ν και πάνω η python γίνεται τάξεις μεγέθους πιο αργή σε σχέση με τα vectorized operations του numpy. Για πολύ μικρά N δεν αποκλείεται η Python να είναι και πιο γρήγορη γιατί δεν χρειάζεται type conversions. https://hackernoon.com/speeding-up-your-code-2-vectorizing-the-loops-with-numpy-e380e939bed3 https://realpython.com/numpy-array-programming/ Επίσης το np.all() δεν είναι το ίδιο με το all() https://stackoverflow.com/a/43382396/592289 Επεξ/σία 7 Μαΐου 2019 από pmav99
Heyho Δημοσ. 7 Μαΐου 2019 Δημοσ. 7 Μαΐου 2019 (επεξεργασμένο) 27 λεπτά πριν, pmav99 είπε Το «πρόβλημα» προφανώς δεν είναι το keyword "for" αλλά το performance. Από κάποιο Ν και πάνω η python γίνεται τάξεις μεγέθους πιο αργή σε σχέση με τα vectorized operations του numpy. Για πολύ μικρά N δεν αποκλείεται η Python να είναι και πιο γρήγορη γιατί δεν χρειάζεται type conversions. https://hackernoon.com/speeding-up-your-code-2-vectorizing-the-loops-with-numpy-e380e939bed3 https://realpython.com/numpy-array-programming/ Επίσης το np.all() δεν είναι το ίδιο με το all() https://stackoverflow.com/a/43382396/592289 Το performance δεν το σκέφτηκα, εστίασα στο paradigm και τον αλγόριθμο. Συμφωνώ για το performance των vectorized operations. Τέλος, ίδια δεν είναι τα all, αλλά έχουν επανάληψη. Υλοποιούνται με επανάληψη. 28 λεπτά πριν, tsofras είπε @Heyho πολύ χολή ρε φίλε έβγαλες σε κόσμο που προσπάθησε απλά να βοηθήσει. Χίλιες φορές να συνεργάζομαι με άτομα σαν τα παιδιά που υποβιβαζεις παρά με άτομα σαν και εσένα. Εξήγησέ μου με ποιον τρόπο κάποιος βοηθάει τον ΟΡ όταν ο ίδιος παραδέχεται ότι δεν γνωρίζει αυτό για το οποίο ρωτάει ο ΟΡ. Πάτε καλά ορισμένοι; Μπαίνει κάποιος και ρωτάει κάτι πολύ συγκεκριμένο: Πώς μπορώ να κάνω κάτι ΣΤΗΝ ΓΛΩΣΣΑ PYTHON. και το γράφει δύο φορές ότι είναι για Python. Μία στον τίτλο και μία στο κείμενο. Πετάγεται ένας και απαντάει, λέγοντας μετά ότι δεν γνωρίζει Python, και πάτε και τον υπερασπίζεστε ότι και καλά «βοηθάει». Πώς; Πώς βοηθάει ΑΦΟΥ ΔΕΝ ΓΝΩΡΙΖΕΙ ΓΙΑ ΝΑ ΑΠΑΝΤΗΣΕΙ; Δεν το λέω εγώ ότι δεν γνωρίζει. ΤΟ ΕΙΠΕ Ο ΙΔΙΟΣ! Πάτε καλά; Επεξ/σία 7 Μαΐου 2019 από Heyho
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα