Idiomatic way to do basic pattern matching on multiple variables in Python

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


Idiomatic way to do basic pattern matching on multiple variables in Python



I want to achieve what this code (written in Crystal) does:


enum PieceKind
Pawn, Rook, Bishop, Knight, King, Queen
end

def piece_kind_at_init(x, y)
case y
when 2, 7 then PieceKind::Pawn
when 1, 8
case x
when 1, 8 then PieceKind::Rook
when 2, 7 then PieceKind::Bishop
when 3, 6 then PieceKind::Knight
when 4 then PieceKind::King
when 5 then PieceKind::Queen
end
end
end



This is the "nicest" version I was able to come up with in Python:


class PieceKind(Enum):
Pawn = auto()
Rook = auto()
Bishop = auto()
Knight = auto()
King = auto()
Queen = auto()

def piece_kind_at_init(x, y):
if y in [2, 7]:
return PieceKind.Pawn
elif y in [1, 8]:
if x in [1, 8]:
return PieceKind.Rook
elif x in [2, 7]:
return PieceKind.Bishop
elif x in [3, 6]:
return PieceKind.Knight
elif x == 4:
return PieceKind.King
elif x == 5:
return PieceKind.Queen



It's fine, but it's definitely less readable the version with proper pattern matching. What's the most idiomatic way to write the code?





If you're looking for a switch statement, python doesn't have those - elif chains as you've written them are the way to go.
– Ben Jones
16 mins ago


switch


elif





Alternantively, you might just define all your y = 1 pieces in a list as so: [Piecekind.Rook, Piecekind.Knight, Piecekind.Bishop, ...]
– Ben Jones
14 mins ago


list


[Piecekind.Rook, Piecekind.Knight, Piecekind.Bishop, ...]





Since this question is about style/Pythonic idioms, you may be interested in the reasoning behind this: docs.python.org/3/faq/…
– Ben Jones
4 mins ago




1 Answer
1



One way to get rid of lengthy elif chain is to create a translation table.


elif


outer_row_pieces = [PieceKind.Rook,
PieceKind.Knight,
PieceKind.Bishop,
PieceKind.King,
PieceKind.Queen,
PieceKind.Bishop,
Piecekind.Knight,
PieceKind.Rook]

def piece_kind_at_init(x, y):
if y == 2 or y == 7:
return PieceKind.Pawn
if y == 1 or y == 8:
return outer_row_pieces[x]
return None






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

How to scale/resize CVPixelBufferRef in objective C, iOS

Stripe::AuthenticationError No API key provided. Set your API key using “Stripe.api_key = ”

SVG with two text elements. When one resizes due to textLength - how to resize the other one to the same character size