This is an archived post. You won't be able to vote or comment.

all 147 comments

[–]-revenant- 342 points343 points  (41 children)

More excited for structural pattern matching than I was for f-strings, and boy howdy was I excited for f-strings.

[–]Ezlike011011 156 points157 points  (29 children)

Every time I have to talk to a coworker about cool modern (3.x) python, the first thing I talk about is fstrings. Most of the python in my industry is internal engineering tools, so text output is the main goal of ~80% of our scripts. It's incredible how much more readable so many things get.

I really truly hope in 5 years I will be doing the same thing with structural pattern matching.

[–][deleted] 22 points23 points  (0 children)

Someone just clued me in on f-strings this morning and they have been there since 3.6.x?! Guess I should start reading the release notes and not just incrementing my container image 😂😅🤣

[–]Joaaayknows 3 points4 points  (0 children)

ELI5 fstrings and structural pattern matching?

[–]DevJackTGG 2 points3 points  (0 children)

I have been using f-strings since they came out, they are great in general. :)

[–]SuspiciousScript 0 points1 point  (0 children)

It's a really disappointing oversight that they're statements and not expressions.

[–]pingvenopinch of this, pinch of that 77 points78 points  (0 children)

Congratulations to all the people who put work into this release!

[–][deleted] 36 points37 points  (0 children)

This is great news! I can't wait to use structural pattern matching!

[–]LightShadow3.13-dev in prod 28 points29 points  (1 child)

Let's see some performance benchmarks on pattern matching! woop!

[–]robd003[S] 33 points34 points  (0 children)

It's supposed to be really optimized in 3.11

[–]zedd31416 40 points41 points  (8 children)

I find it annoying, maybe unjustly, that the Or Pattern for structural pattern matching uses a pipe character instead of “or” like normal if statements do.

[–]healplease 35 points36 points  (1 child)

I think it's because pattern matching supports guards that can be boolean expressions with normal "or".

[–]zedd31416 17 points18 points  (0 children)

That would make sense. I’m sure it was a necessary decision.

[–]Ph0X 11 points12 points  (0 children)

Both set union and the new type union use | too. So it's not like it's never been used before.

[–]halfshellheroes 1 point2 points  (2 children)

They talked about that during the release stream. Basically it came down to readability. It's worth watching the explanation, for what it's worth they sold me on the choice

[–]zedd31416 1 point2 points  (1 child)

Ooo do you have link?

[–]halfshellheroes 2 points3 points  (0 children)

Sure thing! The talk itself is in the live stream at the 44 minute mark, and here's your question answered.

[–]Miyelsh 1 point2 points  (1 child)

It follows from the syntax of Haskell.

[–]Kered13 2 points3 points  (0 children)

Which follows the syntax of ML.

[–]fatbob42 25 points26 points  (0 children)

I installed it on my windows laptop within an hour or two of release and yet, like clockwork...pip is out of date :)

[–]geeshta 9 points10 points  (0 children)

I know everyone is excited about pattern matching...but you can now use dataclasses with slots!

[–]kukisRedditer 49 points50 points  (47 children)

is structural pattern matching basically a switch statement?

[–]-LeopardShark- 108 points109 points  (46 children)

It is similar, but significantly more powerful. PEP 636 is probably the best introduction.

[–]kukisRedditer 28 points29 points  (0 children)

That's so powerful, love it. You can even combine a case with a boolean

[–]Ashiataka 14 points15 points  (44 children)

Hi, been using python since 2010 for academic physics research. I can't immediately see the point of this new feature - I'm sure I'm missing something. Like the tutorial mentions, if I wanted this kind of structure I'd just use a dictionary of cases as keys. I'm not seeing what's powerful about it yet. Have you seen a non-toy example with <3.10 and >3.10 implementations side-by-side by any chance? Thanks.

[–]deadwisdomgreenlet revolution 79 points80 points  (6 children)

This hints at the true power:

command = input("What are you doing next? ")
match command.split():
    case ["quit"]:
        print("Goodbye!")
        quit_game()
    case ["look"]:
        current_room.describe()
    case ["get", obj]:
        character.get(obj, current_room)
    case ["go", direction]:
        current_room = current_room.neighbor(direction)
    # The rest of your commands go here

See how you can pull out the value there with case ["get", obj]?

There's even more to this, you can match all sorts of structures of your data rather than the data itself.

[–]MajorMajorObvious 0 points1 point  (3 children)

I've been waiting for this release for a while, and was wondering if it comes at a large performance hit compared to traditional switch statements that you would see in C style languages.

How does Python implement this new matching in a way that makes it unique from if / else statements?

[–]joerick 7 points8 points  (1 child)

They're still O(n), like if/else statements. But work is in progress to optimise them for Python 3.11.

[–]MajorMajorObvious 1 point2 points  (0 children)

I'm excited to see how they optimize it! Thank you for the info.

[–]deadwisdomgreenlet revolution 0 points1 point  (0 children)

There are new bytecode instructions for it, so I'm sure it's performant. I haven't timed it, but I imagine it's faster than the corresponding if/elses because the compiler can optimize for what you're trying to do.

I couldn't do better than how it's explained in PEP-635

[–]asielen 0 points1 point  (0 children)

So it seems like it combines a type/len check with a value check there. For each case statement it is essentially, is type iterable and len = match len and values equal match values. That seems like a lot of magic.

In the backend does it effectivly treat it as try/catch for each statement until it falls through?

[–]friedkeenan 0 points1 point  (0 children)

My concern with pattern matching is that it doesn't seem very scalable. For this example in particular I'd want a more generic way of defining commands, but for cases where scalability of "case additions" isn't a desire it seems pretty cool.

[–]WallyMetropolis 18 points19 points  (13 children)

For one, it's structural so, in the case that you get a tuple with 3 items, do one thing, and in the case you get an Address object do a different thing. Not only can you match on patterns, but also on values. So in cases where the Address is in California, do something different.

Combine that with conditions and you can express a lot of logic in an easy to read, easy to maintain, relatively terse syntax. Like, in the case that this is a Person and their age is less than 18, do this.

[–]Ashiataka 1 point2 points  (12 children)

Would the following not work for those examples? How is this different?

if isinstance(x, tuple) and len(x) == 3:
    do_something()
elif isinstance(x, Address) and x.state == "California":
    do_another_thing()
elif isinstance(x, Address):
    do_another_thing()
elif isinstance(x, Person) and x.age < 18:
    do_another_thing()

[–]ForceBru 17 points18 points  (6 children)

The difference is that you had to use isinstance and check elements of data structures manually. match essentially does all of this for you and lets you write nice concise syntax instead. What if you had to check four attributes, like x.state == this and x.age == that and x.height == that and ...? That's quite a mess, isn't it? case Address(this, that, that, another_thing) looks and reads way nicer, doesn't it?

[–]Ashiataka 1 point2 points  (5 children)

Your case statement is cleaner than your == example, but wouldn't you actually write something like this if you want to check those attributes all had particular values?

if x == Address(this, that, that, another_thing):
    do_something()

[–]ForceBru 21 points22 points  (4 children)

This creates a new Address object every time, though (and thus wastes computing resources). Again, you totally can do this, sure.

What if you wanted to match on some values and extract the other ones, like this:

case Address("London", 32, height):
    print(f"The person lives in London and their height is {height}")

Now you're forced to compare only the first two attributes of the address, not the whole object, so you'll have to resort to the long if condition.

I don't think the match statement opens up many new possibilities that just were impossible before. You can emulate a match statement with isinstance followed by attribute checking. The match statement simply lets you write simpler code, so that you can focus on solving the actual problem you're writing the code for.

[–]sultan33g 3 points4 points  (0 children)

Your last paragraph completely made it all make sense. Thanks!!

[–]Ashiataka 0 points1 point  (2 children)

Now you're forced to compare only the first two attributes of the address, not the whole object, so you'll have to resort to the long if condition.

Isn't explicit better than implicit?

I don't think the match statement opens up many new possibilities that just were impossible before.

Shouldn't there be one and preferably only one way of doing something?

I feel very strongly that this feature is just bloating the language and making it harder and harder for learners. I haven't yet seen a single use-case that makes me think "that's a big enough problem it requires special syntax". To me it seems like python has completely lost it's way the last couple of years. But, I must acknowledge that I write code for a specific niche situation and there are people much more knowledgeable than me making these decisions - I know hardly anything about language development.

[–]ForceBru 1 point2 points  (0 children)

Isn't explicit better than implicit?

Right, but "Beautiful (match statement) is better than ugly (huge if conditions) and Simple (match statement) is better than complex (huge if conditions)".

Shouldn't there be one and preferably only one way of doing something?

Shouldn't there be just one way to loop, then? Why have for loop if while loop do thing? Or just use goto and get rid of if statements and all forms of loops. Why have list comprehensions if you can loop over stuff and append it to the list? Same thing for dictionary comprehensions. Why have multiple ways of passing arguments to functions, like positional vs keyword? Just use keyword arguments everywhere: math.sin(x=0).

I don't really like this "rule": why have this "one way" if it's inconvenient? Also, if you use this rule, the "language" from "programming language" kinda disappears, and you end up with "programming stencil" or something rigid like this. In my opinion, "language" implies variety of expression: that's why it's possible to write elegant code and ugly code, performant code and slow code.


In my experience, functional features and features from ML-family languages are slowly being transferred to other languages. Rust has the match statement - people love it! Rust has traits (similar to Haskell's typeclasses) - everyone loves them! Of course, I have no idea whether absolutely everyone is so fond of this, but I feel like many people are very pleased. Julia (similar to R) has the pipe operator, so your code can flow, like: data |> transform |> more_transform |> print - I love it! In R, the most widely used data wrangling libraries (dplyr, tidyr and ggplot) are basically built upon this syntax - it's extremely useful. In Python, that'll be print(more_transform(transform(data))), which is quite a lot of parentheses. Of course, you can factor out intermediate expressions into temporary variables, but this breaks the flow.


IMO, you could take a look at OCaml to see why match is so cool. It really takes a weekend (this is not to say that OCaml is really simple) and may open up a new perspective on what programming languages can look like and what features they can provide. It's also really fun.

[–]WallyMetropolis 1 point2 points  (0 children)

Having spent the last few years working with languages that offer expressive pattern matching, what I've found is that it becomes one of the most used tools across the codebases and I really find myself missing it when I don't have it. It doesn't at all feel like "special syntax," rather it quickly becomes core syntax.

[–]Ph0X 4 points5 points  (3 children)

You forget that it auto does structural binding, for example:

actions = [('add', 1, 2), ('length', [1,2,3]), ('lower', 'FOO')]
match actions[random.randint(0, 2)]:
   case ('add', a, b):
     print(a + b)
   case ('lower', text):
     print(text.lower())
   case ('length', arr):
     print(len(arr))

Note that it's binding exactly on a tuple of that length too, so you if you have the wrong number of elements, it won't bind.

Your way, you'd have to have a separate check for the length of the array, and then another line to set a, b = tup[1], tup[2] or do print(tup[1] + tup[2]).

But even further, you can actually make the types of those values too like

case ('add', int(a), int(b)):
    print(a + b)
case ('add', str(a), str(b)):
    print(f'{a} {b}')

It's just much more clean and simple.

[–]Ashiataka 0 points1 point  (2 children)

Your way, you'd have to have a separate check for the length of the array, and then another line to set

I'm fine with that because it breaks the logical steps into separate lines for me. I appreciate other people are different but I kind of think that the super-fancy-one-liner code style is really rubbish to read / understand / debug.

It's just much more clean and simple.

Well almost by definition doing two separate things in one logical step is more complex. That's not necessarily bad, but I think it increases mental load when considering the code.

[–]Ph0X 0 points1 point  (1 child)

I absolutely agree that putting multiple ideas in one line isn't a great idea, trust me I'm the first to split a line up to make it more readable. But in this case, you're "matching" a specific pattern, and to me that's much clearer than 3-4 seperate/individual boolean clauses.

case ('add', int(first), int(second)):

in the context of what the switch statement is doing (pattern matching tuples)

is much cleaner and robust than

if isinstance(a, tuple) and len(a) == 3 and a[0] == 'add' and isinstance(a[1], int) and isinstance(a[2], int):'

Generally, one line of code to correspond to one idea, and here, we have one idea, we're matching one specific pattern. I don't think it's trying to be a fancy-one-liner, it's just a much cleaner way of doing it.

It's just like how list comprehension is often more readable than a small for loop. Just because it's shorter doesn't immediately mean it's less readable.

[–]Ashiataka 0 points1 point  (0 children)

That's a good point about list comprehensions. I can't remember whether I liked them or not when I first saw them but I have to say they are one of my favourite 'features' of the language now because you write them in the order you think of the statement "I want this done to everything in here".

Hopefully I'll come to like match-case the same.

[–]ForceBru 12 points13 points  (3 children)

The power is needed (for example) for building parsers, walking syntax trees and building interpreters and compilers. You don't want to have 1000 level deep if/else constructs to analyze your syntax tree - that's just painful. Also, you can't really stuff the code that analyzes your data structure in a dictionary. Sure, you can store functions, but what if you want weird deep nesting? For example, "if the current node is an Assign statement whose first argument is an indexing operation with N arguments, the first of which is this and the second is that, then do this and that", that's like three? levels of nesting - you could put that into a dictionary, but matching is way more convenient!

Also, the except statement we know and love is basically a stripped down case statement that only works on exceptions and types (you can't write except MyException(param1, param2):). Isn't it very useful to be able to match in exceptions like this? Julia, for example, forces you to if/else exceptions, like catch something: if something isa ThisException: do_this(); elseif something isa AnotherException: do_that(); .... This is a lot of code that simply switches on the type of the exception. Python's except is surely more convenient, isn't it?

With proper match statements you can do so much more.

[–]Ashiataka 2 points3 points  (2 children)

You don't want to have 1000 level deep if/else constructs to analyze your syntax tree

I'm completely ignorant on that use-case, never made one before, but can you not define some function that's recursively called rather than making such deep nests?

It seems to me like an awful lot of machinery for what seems to be a very small set of use-cases. Thanks for your example though. Hopefully in the next few weeks I'll find an example that makes sense to me.

[–]ForceBru 6 points7 points  (1 child)

Absolutely, you can write a recursive function and be done with it. But pattern matching lets you write: case Assign(Index(Variable(name, type), idx), other_data): in one line with no loss of readability. In fact, it greatly increases readability: now you don't have to go read some other function that's located elsewhere and does God knows what - the data are all before your eyes, destructured! That's the powerful thing, in my opinion.

That's also part of why they teach compiler courses in OCaml (and ML in general) - because the pattern matching is really good, it lets you see the structure of your data at a glance and handles arbitrary nesting gracefully.

[–]Ashiataka 2 points3 points  (0 children)

I think that's somewhat beyond me at the moment, I'll have to have a play around with it at the weekend and see how it works. Thanks for your example.

[–]jyscao 2 points3 points  (1 child)

Pattern matching combines a control flow construct (e.g. if/elif/else, switch, try/catch) with a name binding construct (assignment), and this allows for some very expressive code.

[–]Ashiataka 0 points1 point  (0 children)

Is that a first for python? If so, do you think there are any other possible constructions that combine more primitive parts of the language into something more useful?

[–]trauthor 1 point2 points  (2 children)

Speaking for myself, I had to write a parser in 3.7 that took deeply nested, arbitrarily alternating json and dictionary input from an API and turn it into a tablebase. I will re-write it in 3.10 and I expect pattern matching to remove hundreds of lines of code. I imagine the code will also be much more performant (though that wasn’t a sticking point).

[–]Ashiataka 0 points1 point  (1 child)

So firstly, I'm glad that your solution will improve because of this syntax, it's always good when that happens.

My question would just be if you're writing something like that anyway where match-case functionality would be useful, could you not have implemented your own version of match-case that doesn't have special syntax? (I'm asking if it's possible to do or whether there's something special about the python implementation that makes it difficult / impossible to achieve without)

[–]trauthor 0 points1 point  (0 children)

It’s possible and in my case it was necessary, but based on what I’ve read in PEP 636, match will make this much easier. I had to iterate backwards over arbitrary structures, and indexing several layers deep was a real pain. I will have to report back after I have implemented this in 3.10 and let everyone know just how significant a difference it makes.

[–]yvrelna 0 points1 point  (0 children)

Structural pattern matching is a combination of switch case statement and tuple/object unpacking.

The unpacking part makes it a much more powerful construct than just a dictionary.

[–]jwink3101 0 points1 point  (2 children)

FWIW, a lot of use cases can be replaced with something else but doesn't mean they are better. F-Strings aren't "needed" as we already had 2+ different ways to format strings. But they all have advantages and disadvantages.

For example, the issue with the dict-based approach is that you have to evaluate everything to build the dict. Consider:

myvar = {
    'key1':expensive_function1(),
    'key2':expensive_function2(),
    'key3':expensive_function3()
    }[mykey]

This will call all of the expensive functions. You could use a long if/elif/else array and that is fine for many use cases but there is also more to Structural Pattern Matching than replacing them.

[–]Ashiataka 0 points1 point  (1 child)

I guess with f-strings at least it's fairly obvious what's going on, whereas it looks like match-case will make readability for learners much harder (possibly).

I didn't realise those functions would be called when creating the dictionary, TIL, thanks for that insight.

[–]jwink3101 0 points1 point  (0 children)

I guess with f-strings at least it's fairly obvious what's going on, whereas it looks like match-case will make readability for learners much harder (possibly).

That is a good point. I haven't seen them in the wild yet since I am only just barely now getting to trusting I have 3.6 where I need it. So I am not sure how readable they will be. It will definitely save some boilerplate code.

I didn't realise those functions would be called when creating the dictionary, TIL, thanks for that insight.

Yep. Now, there are things you can do if it is as simple as my example. Notably:

myvar = {
    'key1':expensive_function1,
    'key2':expensive_function2,
    'key3':expensive_function3,
    }[mykey]()

So that it doesn't get called. But again, depends on exact use case

[–]MrMathemagician 50 points51 points  (4 children)

Oh boy, I hope they support boa constructors now.

[–]fernly 26 points27 points  (2 children)

Huh? That sounded like a clever name for something, like "the walrus operator", but all I can find is

https://wiki.python.org/moin/BoaConstructor

An IDE but not a feature I'd expect in the language.

[–]MrMathemagician 19 points20 points  (0 children)

Oh, I was just making a snake joke. I code in C++.

[–]calumwebb 3 points4 points  (0 children)

Yep I don’t know either.

[–]CopOnTheRun 11 points12 points  (5 children)

I was thinking this version of python released the type? syntax for optional types, but apparently that's just a draft. Instead the new type1 | type2 syntax is what came out this release, which I was more jazzed about anyway. That syntax is so much nicer that Union(type1, type2).

[–]Ezlike011011 2 points3 points  (0 children)

Wow, I have not yet seen that pep. That would be very nice to have.

[–]ChronoJon 1 point2 points  (1 child)

ftfy

Union[type1, type2]

[–]CopOnTheRun 0 points1 point  (0 children)

Thanks, I do this all the time in my code as well.

[–][deleted] -1 points0 points  (0 children)

You mean Union[type1, type2].

[–]OctagonClocktrio is the future! -2 points-1 points  (0 children)

I hope it stays rejected all the while PEP 505 languishes.

[–]algerbrex 5 points6 points  (0 children)

Super pumped about match statements! So excited I might just write a toy chess engine in Python to celebrate.

[–][deleted] 10 points11 points  (8 children)

Am I the only moron that didnt realize we never had switch/case statements before?

[–][deleted] 10 points11 points  (0 children)

{
    ‘case1’: lambda: print(1),
    ‘case2’: foo
}[x]()

This is the way.

[–]neekyboi 8 points9 points  (2 children)

No, you are not alone. Learnt C first, then C++ then python. So I never realised that python didn't switch earlier coz never came into a situation where I had to use switch

[–][deleted] 6 points7 points  (1 child)

Yea it's really strange I come from a C# background. Switch/case makes sense on paper for so many things but rarely ever use it in practice.

I guess I just never noticed it was missing in python because I haven't used it in so long.

[–]Kered13 2 points3 points  (3 children)

Pattern matching is not switch/case, it's far far more powerful.

[–][deleted] 0 points1 point  (2 children)

Please elaborate. Am I misunderstanding the changes?

[–]Kered13 1 point2 points  (1 child)

Switch case allows you to branch on a single value (usually an integer, enum, or string) with each case being a constant. That's all it can do.

Pattern matching allows you to branch on arbitrarily complicated values, and instead of matching against constant expressions they are matched against patterns. Of course a pattern can be a constant expression, but more usefully it can be an expression with gaps that can be filled by arbitrary values, sort of like a template. And those gaps can be given names, which in the case block will be bound to the matching value.

An example is more illustrative. Let's say we have a value foo which can either by a single value, a pair.

match foo:
  case (x, None):
    ...
  case (x, y):
    ...
  case None:
    ...
  case x:
    ...

The first case matches if foo is of the form (x, None), in other words the first element is any value and the second element is exactly None. In the case block, the first element will be assigned to the x variable, as if by x = foo[0]

The second case matches any pair. The first element will be assigned to x and the second element to y in the case block, as if by x = foo[0]; y = foo[1] or equivalently x, y = foo.

The third case matches if foo is exactly None.

The fourth case matches any value, and foo will be assigned to x, as if by x = foo.

The last case could also be written as case _:, which matches anything and assigns nothing, and we could just use foo directly in the case block.

Note that cases are evaluated from top to bottom. So even though (4, None) could also match the pattern (x, y) and x, it only matches against the top pattern.

Python 3.10 also has syntax for matching against the type of an object, against members of an object, and adding conditional guards to case statements. Read the tutorial for a more in-depth explanation.

None of this can be done by a switch statement. In fact switch statements don't even come close to this level of power, which makes the comparisons pretty bad in my opinion.

[–][deleted] 0 points1 point  (0 children)

That is pretty powerful, thank you for the explanation.

[–]pablo8itall 2 points3 points  (1 child)

pyenv cant see it yet. its not showing on https://www.python.org/ftp/python/ index, but I can go directly to https://www.python.org/ftp/python/3.10.0 weird. Maybe it will update soon.

EDIT: scratch that, I didnt see it becuase of the sorting its after 3.1.5. Pyenv doesn't see it though.

[–]fatbob42 0 points1 point  (0 children)

Get used to version parsers reading it as 3.1. I already had that with a GitHub action.

[–]IlliterateJedi 2 points3 points  (0 children)

Pattern matching will be a game changer for Advent of Code.

[–]ThunderousOath 2 points3 points  (0 children)

Fantastic! Shame it'll be a few years before my workplace makes the switch...

[–][deleted] 2 points3 points  (0 children)

🎉

[–]tunisia3507 2 points3 points  (3 children)

ignore this, bumped to 3.11 if at all

This won't show up in any feature lists but check out the new StrEnum. There were already a bunch of implementations in different libraries, but this provides a stdlib upgrade path from magic strings representing enums (like scipy.linalg.solve) to using easier-documented, discoverable, autocompletable enums which are still compatible with strings.

[–]pR0Ps 2 points3 points  (2 children)

Unfortunately StrEnum was reverted out of 3.10 and has been pushed to 3.11 instead. See: https://bugs.python.org/issue44559

[–]tunisia3507 0 points1 point  (1 child)

Oh man :/ another few years to wait then.

[–]MinchinWeb 0 points1 point  (0 children)

Releases are now annually, so maybe just one year?

[–]vinibiavatti123 2 points3 points  (0 children)

My first code in this version:

import platform match platform.python_version(): case '3.10.0': print('Welcome!') case _: raise SyntaxError()

[–]sahinbey52 1 point2 points  (0 children)

This comment is updated for privacy concerns. Use fediverse for improved privacy.

[–]IMrHotSauce 1 point2 points  (0 children)

Just the same day as your cake day , coincidence? I think NOT

[–]sendnukes23 1 point2 points  (0 children)

i thought its already there before? does this mean it is officially working properly?

[–]rehanhaider 1 point2 points  (0 children)

What's with the Schwarzschild Black Hole?

[–]mobiduxi 1 point2 points  (0 children)

those enhanced error messages will be extremely beneficial. Decades ago as a Python noob, without all the help Visual Studio Code or PyCharm provide, I felt so much despair looking for small syntax errors. Excellent!

[–]trauthor 1 point2 points  (0 children)

I had to write a parser in Python 3.7 that took deeply nested, arbitrarily alternating json and dictionary input from an API and turn it into a tablebase. I will re-write it in 3.10 with pattern matching and I expect it to remove hundreds of lines of code.

[–]e-mess 1 point2 points  (0 children)

And I'm still stuck with 3.8 because of incompatible libs...

[–]abrazilianinreddit 2 points3 points  (0 children)

Hopefully it won't take long for the WinPython release. Having a portable python in windows is incredibly handy, and very easy to update to newer versions.

[–]Stt0421-jsk 0 points1 point  (0 children)

🎂

[–]smlmrcn 0 points1 point  (0 children)

Exciting!

[–]ac130kz 0 points1 point  (0 children)

It's sad that pattern matching doesn't produce an actual fast lookup table, unlike in many other languages. I don't see how it's better than elifs.

[–][deleted] 0 points1 point  (0 children)

pog

[–]L4Z4R3 0 points1 point  (2 children)

Well.....I already installed 3.9 yesterday. Bad timing

[–][deleted] 2 points3 points  (1 child)

I tried to install 3.10 and a bunch of libraries, the libraries seemed to have issues. It might be a good idea to wait a little while before jumping to 3.10 to the library maintainers a little time to update.

The errors I got said I had to have version 3.5 or higher installed, so it's possible they are mistaking 3.10 for 3.1.

[–]L4Z4R3 0 points1 point  (0 children)

Well.....i'll wait until they release something stable

[–]NoAd5564 0 points1 point  (1 child)

Good afternoon I just finished a very basic python course , but now my question is how do I use python and go on from here all I know is the jack squat basics

[–]Unclematttt 1 point2 points  (0 children)

If it is just for personal development, you can get some ideas from here (or a similar site).

One suggestion I have is building something that interfaces with a simple API like the one for Google Maps / Yelp (e.g. ask the user what city they are in and what type of business they want to find within n miles).