2013-04-11 17 views
14

To pytanie jest dla zabawy; Nie oczekuję, że odpowiedź będzie przydatna.Czy istnieje wbudowana funkcja "i" i/lub "lub" w języku Python?

Kiedy widzę ludzi robiących rzeczy z reduce() w Pythonie, często korzystają z wbudowanej funkcji w Pythonie, często z modułu operator.

to działa:

result = reduce(lambda a, b: a + b, range(5)) 

Ale zazwyczaj można zobaczyć poniżej:

from operator import add 
result = reduce(add, range(5)) 

Co jest dla mnie dziwne jest to, że moduł operator nie wydaje się mieć funkcję logiczną and. Ma on bitowy i, ale nie jest logiczny and.

Więc załóżmy, robisz to:

result = reduce(lambda a, b: a and b, range(1, 6)) 

Czy istnieje wbudowana funkcja, która może być używana tutaj?

Zastanawiam się również, czy istnieje wbudowana funkcja, która może zastąpić or.

Jeśli map argumenty do wartości logiczne pierwsze, można użyć bitowego iz operator, lub po prostu korzystać bezpośrednio bool.__and__, tak:

from operator import and_ 
result = reduce(and_, map(bool, range(1, 6))) 
result = reduce(bool.__and__, map(bool, range(1, 6))) 

i podobnie z operator.or_() lub bool.__or__ dla funkcjonowania or. Ale szukam funkcji, która nie potrzebuje wartości odwzorowanych na Booleans.

Jeśli wiedziałeś na pewno, że twoje wartości są liczbami całkowitymi, możesz użyć operator.mul dla and i operator.add dla or. Byłoby to surowe włamanie i nie chcę tej odpowiedzi ... szczególnie biorąc pod uwagę, jak drogie byłyby mnożenia, gdyby napotkano wiele liczb i żadna z nich nie była zerowa!

Uwaga: jestem świadomy all() i any(), które są lepszymi zamiennikami do tego zastosowania reduce(). Jak powiedziałem na górze, proszę o to dla zabawy.

Uwaga: Funkcja, która ma efekt uboczny wymuszenia wszystkich wartości na bool, byłaby akceptowalną odpowiedzią. Wbudowany and Hasło nie to zrobić:

x = 3 and 5 # sets x to 5, not to True 

Jednak dla celów niniejszego pytanie Jestem zainteresowany tylko w funkcji, która może pracować z reduce() zrobić logiczne and lub or operacje.

+1

można użyć 'dowolny ((a, b)) 'dla' a lub b' i 'all ((a, b)) dla' a i b'. Oczywiście, musisz tworzyć krotki i nie ma żadnych zwarć ... – kindall

+1

'x = 3 i 5' ustawia' x' na '5', ale możesz też przesłać go do boolowskiej, więc dlaczego nie używasz tego? Chodzi o to, że niezależnie od wyrażenia logicznego, które próbujesz ocenić 'x' w, będzie interpretowane jako boolean. – whatyouhide

+1

@steveha ładne pytanie. Mam nadzieję, że dostaniesz odpowiedź, ale wygląda na to, że przeszedłeś każdą alternatywę już w swojej odpowiedzi – jamylak

Odpowiedz

6

Chyba rzeczywisty powód dlaczego nie ma and i or w module operatora jest to, że jest to niemożliwe do oceny argumentów funkcji w sposób zwarcia - który jest całym punktem operatorów boolowskich. Tak więc odpowiedź na twoje pytanie brzmi: nie, nie ma wbudowanej funkcji, która mogłaby naśladować and/or, ani też nie można jej napisać.

all/any stosowane do generatorów są zwierania także

def gen(): 
    yield 1 
    yield this_wont_be_evaluated 

print any(gen()) 

ale nie mam pojęcia jak zrobić, że praca z argumentami run-time

+0

Aha! To jest odpowiedź. –

+2

Myślałem, że zwarcie jest po prostu użyteczną własnością operatorów logicznych, a nie "całego punktu". –

+3

To jest dokładnie odpowiedź na zadane pytanie: W module operatora nie ma żadnych funkcji "i" i "lub", ponieważ nie można zdefiniować tych funkcji. Posiadanie funkcji, które są blisko, ale nie to samo, byłoby po prostu mylące. –

0

Uwaga: Funkcja, której efektem ubocznym jest wymuszenie wszystkich wartości na wartość bool , byłaby akceptowalną odpowiedzią. Wbudowany i Hasło nie zrobić

ale wbudowany not kluczowych robi.

In : not 255 
Out: False 

In : not 0 
Out: True 

oczywiście, będziesz musiał dostać logiki do tyłu, a następnie:

In : not (not 5 and not 0) # mimics: 5 or 0 
Out: True 

tak, to z tego można emulować poprzez reduceall(), map i operator.*:

In : not reduce(operator.or_,map(operator.not_,[1,2,3,4,5])) # mimics all(1,2,3,4,5) 
Out: True 

In : not reduce(operator.or_,map(operator.not_,[1,2,3,0,5])) # mimics all(1,2,3,0,5) 
Out: False 

jest to (rodzaj), co chcesz osiągnąć? Obawiam się, że nie możemy się zbliżyć.

+0

Obawiam się, że nie widzę, jak mógłbym użyć któregokolwiek z powyższych w instrukcji 'reduce()'. Potrzebuję wywołania, a jeśli muszę napisać 'lambda', aby zamknąć jakiś kod, po prostu napiszę' lambda', która wywoła argumenty 'i' lub' lub'. – steveha

+0

cóż, nie potrzebujesz lambda, jeśli zezwolimy na 'map()', zobacz edycję. – ch3ka

+0

Sugerujesz użycie 'not' do odwzorowania wartości na Booleans, ale zauważysz, że musielibyśmy wtedy odwrócić logikę. Sugeruję, że prostsze byłoby użycie 'bool()' do odwzorowania wartości na Booleans, ponieważ wtedy nie musielibyśmy odwracać logiki.Zobacz oryginalne pytanie na ten przykład, zaczynając od tekstu "Jeśli najpierw odwzorujesz argumenty na Booleans". – steveha

1

Nie ma wbudowanych funkcji, o których wiem, że to robią. Można jednak określić banalne funkcje, które owijają się wokół operatorów:

>>> def newand(a,b): 
... return a and b 
... 
>>> def newor(a,b): 
... return a or b 
... 
>>> reduce(newand, map(bool, range(5))) # Will return False, because bool(0) == False 
False 
>>> reduce(newand, map(bool, range(1,5))) # Now 0 is excluded 
True 
+0

To jest to samo co 'lambda', nie jest to funkcja wbudowana, o którą pytano – jamylak

+1

Na to też odpowiedziano, zarówno w mojej odpowiedzi, jak i na innych, a mianowicie, że te nie istnieją. Co też mnie trapi, ponieważ czuję, że powinni być jego częścią. Niestety, Python nie jest doskonały i to wszystko, co możemy z tym zrobić, ponieważ 'i', 'lub' i 'not' są specjalnymi konstruktami warunkowymi, bliższymi' if' niż zwykłym operatorom (dlatego też możesz ' przeładowują je, kolejny smutny fakt). –

+0

@StjepanBakrac: Dlaczego chcesz przeciążyć 'i' lub' lub 'w jakikolwiek sposób, który nie zgadza się z' __bool__'? –

Powiązane problemy