Pipe character in Python
Asked Answered
A

8

133

I see a "pipe" character (|) used in a function call:

res = c1.create(go, come, swim, "", startTime, endTime, "OK", ax|bx)

What is the meaning of the pipe in ax|bx?

Aalborg answered 13/5, 2011 at 7:29 Comment(1)
this should be interesting to you #28253085Noreen
T
92

It is a bitwise OR of integers. For example, if one or both of ax or bx are 1, this evaluates to 1, otherwise to 0. It also works on other integers, for example 15 | 128 = 143, i.e. 00001111 | 10000000 = 10001111 in binary.

Toughen answered 13/5, 2011 at 7:31 Comment(8)
How about when I type 5|7 in the shell? It returns 7. why?Aalborg
Because that's what bitwise OR does.Nephew
5 = 101, 7 = 111, 101 | 111 = 111 = 7Turenne
@Ignacio: Python does not have a logical or operator?! What do you call or, then?Kingpin
@Ignacio are you referring to it as a null coalescing operator (like in C#/Perl)? Never heard of it referred to that way, but if I understand correctly, that does make sense in a way since it's a short-circuit operator. Is that what you were referring to (do I understand you properly)?Ulises
@zeekay: Correct. Rather than always returning True or False, and and or always return one of their operands, hence "coalescing" rather than "logical".Nephew
It's not strictly bitwise. (True | False) is True whereas (True | 0) is not True. There are different overloadings of | in python 2.6 depending on whether the arguments are the special integral values (True, False) vs regular integral values.Pharisaic
What Mike said. More generally, it calls the __or__ method of the first operand with the second operand, so you can define its behavior for your own classes.Sheri
M
206

This is also the union set operator

set([1,2]) | set([2,3])

This will result in set([1, 2, 3])

Masurium answered 4/3, 2012 at 21:54 Comment(2)
This is likely much more common that bitwise operations.Melissa
Hmm. Pardon @Melissa 🙇‍♀️ Sets have explicit counterpart methods that should be favored. In the codebase I'm dealing with this is used rather exclusively for bit ops.Kahle
T
92

It is a bitwise OR of integers. For example, if one or both of ax or bx are 1, this evaluates to 1, otherwise to 0. It also works on other integers, for example 15 | 128 = 143, i.e. 00001111 | 10000000 = 10001111 in binary.

Toughen answered 13/5, 2011 at 7:31 Comment(8)
How about when I type 5|7 in the shell? It returns 7. why?Aalborg
Because that's what bitwise OR does.Nephew
5 = 101, 7 = 111, 101 | 111 = 111 = 7Turenne
@Ignacio: Python does not have a logical or operator?! What do you call or, then?Kingpin
@Ignacio are you referring to it as a null coalescing operator (like in C#/Perl)? Never heard of it referred to that way, but if I understand correctly, that does make sense in a way since it's a short-circuit operator. Is that what you were referring to (do I understand you properly)?Ulises
@zeekay: Correct. Rather than always returning True or False, and and or always return one of their operands, hence "coalescing" rather than "logical".Nephew
It's not strictly bitwise. (True | False) is True whereas (True | 0) is not True. There are different overloadings of | in python 2.6 depending on whether the arguments are the special integral values (True, False) vs regular integral values.Pharisaic
What Mike said. More generally, it calls the __or__ method of the first operand with the second operand, so you can define its behavior for your own classes.Sheri
V
36

In Python 3.9 - PEP 584 - Add Union Operators To dict in the section titled Specification, the operator is explained. The pipe was enhanced to merge (union) dictionaries.

>>> d = {'spam': 1, 'eggs': 2, 'cheese': 3}
>>> e = {'cheese': 4, 'nut': 5}
>>> d | e
{'spam': 1, 'eggs': 2, 'cheese': 4, 'nut': 5} # comment 1
>>> e | d
{'cheese': 3, 'nut': 5, 'spam': 1, 'eggs': 2} # comment 2

comment 1 If a key appears in both operands, the last-seen value (i.e. that from the right-hand operand) wins --> 'cheese': 4 instead of 'cheese': 3

comment 2 cheese appears twice, the second value is selected so d[cheese]=3

Vidicon answered 8/3, 2021 at 19:56 Comment(1)
I came across with an import statement from SqlAlchemy: S = Session | scoped_session. which suggest it is even works with classes as wellScyphozoan
L
34

Yep, all answers above are correct.

Although you could find more exotic use cases for "|", if it is an overloaded operator used by a class, for example,

https://github.com/twitter/pycascading/wiki#pycascading

input = flow.source(Hfs(TextLine(), 'input_file.txt'))
output = flow.sink(Hfs(TextDelimited(), 'output_folder'))

input | map_replace(split_words, 'word') | group_by('word', native.count()) | output

In this specific use case pipe "|" operator can be better thought as a unix pipe operator. But I agree, bit-wise operator and union set operator are much more common use cases for "|" in Python.

Lerner answered 23/10, 2016 at 0:7 Comment(0)
N
14

Bitwise OR.

Nephew answered 13/5, 2011 at 7:33 Comment(0)
A
8

It is a bitwise-or.

The documentation for all operators in Python can be found in the Index - Symbols page of the Python documentation.

Addlebrained answered 13/5, 2011 at 21:30 Comment(0)
C
8

Summarizing & extending previous answers:

The | operator originally does bitwise OR. Here is a tutorial on bitwise operations.

f'{0b1100 | 0b1010 :04b}' == '1110'

On the other hand, Python operators can be overloaded by overloading their equivalent operator functions. In particular, | can be overloaded by implementing the function __or__ (and __ror__). Any Python library, standard or userbase, can overload any operator (e.g., archived PyCascading).

The Python built-in types such as set and dict overload | to define union and merge, respectively. In particular, Python 3.9, PEP 584, brought the overloaded | and other operators to dict and other standard library types.

# sets; | does union of sets
#  the order does not matter, i.e., the operation is commutative
{1, 2} | {2, 3} == {1, 2, 3}

{2, 3} | {1, 2} == {1, 2, 3}


# dicts; | does "merging" of dicts
#   the order does matter, i.e., the operation is NOT commutative
{'a': 1, 'b': 2} | {'b': 99, 'c': 3} == {'a': 1, 'b': 99, 'c': 3}

{'b': 99, 'c': 3} | {'a': 1, 'b': 2} == {'a': 1, 'b': 2, 'c': 3}

Likewise, the types.UnionType, introduced with Python 3.10, also overloads the binary-or operator |, in this case to signify a union of types for type annotations/hints, e.g., typing.Union[int, str] == int | str.

A recent, popular overloading and usage of the | operator is in the Python LangChain library to chain/pipe operations. This is the exact code for how LangChain overloads the operator.

# LangChain chained sequence of components
chain = prompt | model | output_parser
Chaworth answered 20/9, 2023 at 10:28 Comment(3)
+1 for langchain, i was trying to figure out how exactly it uses pipe operator and missed that runnable thingDorice
This is the best explanation of how langchain performs its 'magic' on the internet. Great comment, thank you.Mors
Excellent answer, I've been looking for a deeper explanation of | operator overloading, and this is exactly what I've been looking for. Let's make writing pipelines and chains in Python a breeze!Mott
K
0

Not specifically in function call but regarding OPs headline one might nowadays also list the pipe operator for "or" functionality in typing annotations!

See: https://docs.python.org/3/library/typing.html#typing.Union

For example:

def get_string_length(string: str | None = None) -> int:
    if string is None:
        string = 'muppets'
    return len(string)
Kahle answered 12/2, 2024 at 14:57 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.