On 2018-05-04 08:26, Jacco van Dorp wrote: > Would this be valid? > > # Pattern matching with guards > x = 'three' > > number = match x: > 1 => "one" > y if y is str => f'The string is {y}' > z if z is int => f'the int is {z}' > _ => "anything" > > print(number) # The string is three > > If so, why are y and z both valid here ? Is the match variable rebound > to any other ? Or even to all names ?
In the match case here: match x: y if y > 3 => f'{y} is >3' # to use an example that works there are three parts: "y" is a pattern. It specifies the shape of the value to match: in this case, anything at all. Nothing is bound yet. "if" is just the word if, used as a separator, nothing to do with "if" in expressions. "y > 3" is the guard expression for the match case. Iff the pattern matches, "y > 3" is evaluated, with names appearing in the pattern taking the values they matched. It's important to note that the thing on the left-hand side is explicitly *not* a variable. It's a pattern, which can look like a variable, but it could also be a literal or a display. > ofc, you could improve the clarity here with: > > number = match x as y: > > or any variant thereof. This way, you'd explicitely bind the variable > you use for testing. If you don't, the interpreter would never know > which ones to treat as rebindings and which to draw from surrounding > scopes, if any. I don't think anything in the pattern should be drawn from surrounding scopes. > I also haven't really seen a function where this would be better than > existing syntax, and the above is the only one to actually try > something not possible with dicts. The type checking one could better > be: > > [snip] > > The production datetime code could be: > > def convert_time_to_timedelta_with_match(unit:str, amount:int, now:date): > return { > "days":timedelta(**{unit: amount}), > "hours":timedelta(**{unit: amount}), > "weeks":timedelta(**{unit: amount}), > # why not something like subtracting two dates here to get an > accurate timedelta for your specific interval ? > "months":timedelta(days = 30*amount), # days = (365.25 / > 12)*amount ? Would be a lot more accurate for average month length. > (30.4375) > "years":timedelta(days=365*amount), # days = 365.25*amount ? > "cal_years":timedelta(now - now.replace(year=now.year - amount)), > }.get(unit) Don't you think the repetition of ``timedelta(**{unit: amount})'' sort of proves OP's point? Incidentally, there's no need to use the dict trick when the unit is known statically anyway. I can't decide if that would count as more reptition or less. > I honestly don't see the advantages of new syntax here. > Unless you hate the eager evaluation in the dict literal getting > indexed, so if it's performance critical an if/else might be better. > But I can't see a match statement outperforming if/else. (and if you > really need faster than if/else, you should perhaps move that bit of > code to C or something.) It's not really about performance. It's about power. A bunch of if statements can do many things--anything, arguably--but their generality translates into repetition when dealing with many instances of this family of cases.
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/